Discord: always use autocomplete for command args with choices to fixinline arg ignored (#32753)#32764
Conversation
… inline arg ignored (openclaw#32753)
Greptile SummaryThis PR fixes a bug where Discord slash commands with static choices (≤ 25 options) — such as Root cause: Fix: Key changes:
Behavioral note: Switching from fixed-choice dropdowns to autocomplete removes Discord's client-side enforcement that submitted values must be from the predefined list. Users can now submit arbitrary free-text values for these args. This is acknowledged in the PR description as "functionally equivalent but allows free typing," but it's worth confirming that downstream command handlers validate or handle out-of-choices values gracefully. Confidence Score: 4/5
Last reviewed commit: 783f01f |
Additional Comments (1)
With fixed-choice dropdowns ( The autocomplete handler filters and surfaces matching choices as suggestions, but that filtering is only advisory; nothing prevents a user from submitting a value that isn't in If downstream command handlers (e.g. for It's worth verifying — or adding a note — that Prompt To Fix With AIThis is a comment left during a code review.
Path: src/discord/monitor/native-command.ts
Line: 123-136
Comment:
**Autocomplete allows arbitrary free-text input — no server-side choice validation**
With fixed-choice dropdowns (`choices: [...]`), Discord enforces on the client side that the submitted value is one of the predefined options. By switching to `autocomplete: true`, Discord no longer validates the submitted value — a user can dismiss the suggestion list and type any string (e.g., `/acp nonexistent_action`) and Discord will pass it through as-is.
The autocomplete handler filters and surfaces matching choices as suggestions, but that filtering is only advisory; nothing prevents a user from submitting a value that isn't in `resolvedChoices`.
If downstream command handlers (e.g. for `/acp`) already validate the received arg value against the known choices and produce a user-friendly error or fall back gracefully, this is fine. But if any handler assumes the value is guaranteed to be a valid choice (as the old fixed-dropdown contract implied), it may now receive unexpected values silently.
It's worth verifying — or adding a note — that `resolveCommandArgMenu` or the command dispatch layer handles an out-of-choices value gracefully for every command that previously used static choices.
How can I resolve this? If you propose a fix, please make it concise. |
|
Superseded by #33136, which consolidates the /acp inline action autocomplete fix plus the bound-thread bot system message guard. Closing in favor of that PR. |
Summary
/acp(and any slash command with ≤ 25 static choices) ignores the inline argument the user types — Discord always sendsaction = null, causing OpenClaw to show the button picker menu instead of executing the requested action directly.buildDiscordCommandOptionsonly enabledautocompletewhen choices were provided via a dynamic function or the count exceeded Discord's 25-option limit. For/acp's 16 static choices both conditions werefalse, so the arg was registered as a fixed-choice dropdown. Discord's fixed-choice dropdown enforces selection from the UI and sendsnullwhen the user types inline;resolveCommandArgMenuthen seesargs.values["action"] == nulland falls through to the ephemeral button menu.shouldAutocompleteis nowtruewheneverresolvedChoices.length > 0, regardless of whether choices are static or dynamic, or how many there are. Discord registers the arg withautocomplete: true, the existing autocomplete handler filters and returns matching choices as the user types, and the typed/selected value is passed through correctly — soresolveCommandArgMenuskips the button menu.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
/acp close,/acp spawn,/acp status(and any other/acp <action>) now execute directly without showing the picker menu.Security Impact (required)
Yes, explain risk + mitigation: N/ARepro + Verification
Environment
channels.discordwith native commands enabledSteps
/acp close(or any/acp <action>) and submit.closeargument is ignored.To verify the fix locally:
src/discord/monitor/native-command.tsshouldAutocomplete = resolvedChoices.length > 0(no additional conditions)pnpm buildandpnpm check; both passExpected
/acp closeshuts down the ACP sub-agent without showing a menu./acpis invoked with no argument.Actual
Evidence
Human Verification (required)
/acp closewithout menu,/acpalone still shows menu, other commands with static choices unaffected functionallyDISCORD_BOT_TOKEN); logic change is isolated to option schema construction.Compatibility / Migration
Failure Recovery (if this breaks)
git revert 783f01fd2src/discord/monitor/native-command.tsRisks and Mitigations
autocomplete: trueregistrations may take a few minutes to propagate. During that window behavior is unchanged (old fixed dropdown still works). No mitigation needed beyond noting the delay.