Repository navigation
fix: Refused a prefix command typed without its subcommand instead of failing - #219
Merged
Merged
Conversation
… failing Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JrFnSipitEXUhVySPKfrMR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
runChecksreads the subcommand once, and refuses a prefix run that names none the command has.t?role @someone @Rolenow gets a short reply that deletes itself: "That command needs one of these after its name:addorremove." The refusal comes after the owner-only, pause, blacklist and switch gates and before the cooldown, so a typo no longer starts one.t?music nonsenseandt?casino nonsenseare refused the same way.pickSubcommandis a new shared reply in all eight languages. It lists the subcommands witheitherOf, so each language joins them its own way.AGENTS.md§5 notes the refusal, and the comment on the prefix reader's lazy parse now says what answers it.Why
This was logged in production:
The prefix reader throws a
UserFacingErrorthe first time it is read when the words typed name no subcommand. That was meant to happen insiderunCommand, where it is answered to the person. ButrunChecksreads the subcommand earlier, for the subcommand's own permissions, and for the music and casino gates before that. Its privatechosenSubcommanddidn't catch the error, so it escaped the handler. The person got no reply, and the operator got an error log for a typo.Slash commands were never affected: Discord makes the reader pick a subcommand, and discord.js's
getSubcommand(false)doesn't throw.How to verify
tests/core/checks.test.tsrunrunCheckson a realPrefixInteraction:t?role @someoneand a baret?roleare refused with the subcommands to pick from, and a correctedt?role add @someonestraight after is let through, so the typo cost no cooldown.checks.tsboth tests fail withUserFacingError: Pick one of: …, the error from the log.npm run checkpasses locally with 4,046 tests; the 30 database suites are skipped there. CI passed on this branch, with the database suites included.t?rolewith no subcommand answers with the refusal, which deletes itself, and nothing is logged aterror. Not tried against live Discord.Checklist
develop, and this pull request targetsdevelopnpm run checkpassessave()on numeric fieldsembed()factoryconsole.*docs/commands.mdis unchangedAGENTS.md§5Generated by Claude Code