Skip to content

fix(discord): cap slash commands at Discord's 100-command limit - #46078

Merged
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
xxxigm:fix/discord-slash-command-100-cap
Jun 15, 2026
Merged

fix(discord): cap slash commands at Discord's 100-command limit#46078
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
xxxigm:fix/discord-slash-command-100-cap

Conversation

@xxxigm

@xxxigm xxxigm commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Bounds the Discord adapter's desired slash-command set so it never exceeds Discord's hard cap of 100 global application commands, fixing recurring 400 Bad Request (error code: 30032): Maximum number of application commands reached (100) sync failures.

The bug

_register_slash_commands() in plugins/platforms/discord/adapter.py registers:

  • ~27 native commands (/new, /model, /stop, …)
  • every gateway-available entry in COMMAND_REGISTRY (~75 CommandDef)
  • all plugin commands (_iter_plugin_command_entries())
  • the consolidated /skill group

On a loaded install (many plugins / quick commands) the desired set goes over 100. Discord then rejects the entire tree.sync() / _safe_sync_slash_commands() batch with error 30032 — so every slash command silently breaks, not just the overflow. This shows up as a traceback on every gateway reconnect.

This is the root cause that the existing open PRs don't cover:

The fix

Cap registration at the 100-command limit:

  • Native commands (registered first → highest priority) and the /skill group are always kept.
  • Lower-priority auto-registered COMMAND_REGISTRY and plugin commands are added only until the cap is reached.
  • A single concise WARNING tells the user how to surface the rest (disable unneeded commands / trim plugins).

Because both sync paths read from tree.get_commands(), bounding the tree fixes the root cause for both.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • plugins/platforms/discord/adapter.py: add _DISCORD_MAX_APP_COMMANDS = 100; cap the COMMAND_REGISTRY and plugin auto-registration loops (reserving one slot for /skill); warn once when commands are dropped.
  • tests/gateway/test_discord_slash_commands.py: register 200 plugin commands and assert the tree stays ≤ 100, native commands survive, and overflow is dropped.

How to Test

scripts/run_tests.sh tests/gateway/test_discord_slash_commands.py

All 34 tests pass; tests/gateway/test_discord_connect.py unaffected.

xxxigm added 2 commits June 14, 2026 17:01
Discord enforces a hard cap of 100 global application commands per app.
The adapter registers ~27 native commands plus every gateway-available
entry in COMMAND_REGISTRY plus all plugin commands plus the consolidated
/skill group. On a loaded install (many plugins/quick commands) the
desired set exceeds 100, so tree.sync() / _safe_sync_slash_commands()
hits error 30032 ("Maximum number of application commands reached") and
Discord rejects the ENTIRE batch — silently breaking every slash command,
not just the overflow.

Cap registration at the 100-command limit: native commands (registered
first, highest priority) and the /skill group are always kept; lower-
priority auto-registered COMMAND_REGISTRY and plugin commands are added
only until the cap is reached, with a single concise warning telling the
user how to surface the rest. Since both sync paths read from
tree.get_commands(), bounding the tree fixes the root cause for both.
Registers 200 plugin commands on top of the native + COMMAND_REGISTRY set
and asserts the tree never exceeds Discord's 100-command limit, that native
high-priority commands survive the cap, and that overflow is actually
dropped. Regression guard for the recurring error 30032
("Maximum number of application commands reached") sync failures.
@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins platform/discord Discord bot adapter P2 Medium — degraded but workaround exists labels Jun 14, 2026
@liuhao1024

Copy link
Copy Markdown
Contributor

Verification: Reviewed the diff — the 100-command cap implementation is clean.

  • _DISCORD_MAX_APP_COMMANDS = 100 constant with clear error-30032 comment
  • Native commands registered first (highest priority), then plugins, then skills group — correct ordering
  • slot_cap = _DISCORD_MAX_APP_COMMANDS - 1 reserves one slot for the consolidated /skill group
  • Warning log when overflow occurs is helpful for operators
  • Test covers the cap enforcement, native command survival, and overflow dropping

One observation: the slot_cap reserves 1 slot for /skill but the skill group registration (self._register_skill_group(tree)) happens after the cap loop and doesn't check against the cap. If the skill group itself registers more than 1 command (e.g., a category subcommand per skill), it could push the total slightly over 100. In practice this is unlikely since Discord counts the group as 1 command with subcommands, but worth noting.

@kshitijk4poor kshitijk4poor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed end-to-end and verified every claim against the current code.

Root cause confirmed. On current main, _register_slash_commands registers 27 native commands + 50 gateway-available COMMAND_REGISTRY entries before a single plugin or /skill — that's already 77. Any install with ~24+ plugin commands pushes the desired set past 100, and Discord then rejects the entire tree.sync() batch with error 30032, silently breaking every slash command (not just the overflow). This matches the reported symptom exactly.

Fix is correct and minimal. Capping at registration time bounds both sync paths, since tree.sync() and _safe_sync_slash_commands() both serialize whatever's in tree.get_commands(). Native commands and the consolidated /skill group are reserved and always survive; lower-priority auto-registered + plugin commands fill the remaining slots. I confirmed the tree never exceeds 100 and native commands (/status, /stop, /new, /model, /help) are preserved.

Verified locally:

  • tests/gateway/test_discord_slash_commands.py — 34/34 pass; test_discord_connect.py (18) and test_discord_slash_auth.py (32) unaffected.
  • The new test is a genuine regression guard — it fails against the unfixed adapter and passes against the fix.
  • This is also the only fix targeting the current path: gateway/platforms/discord.py has moved to plugins/platforms/discord/adapter.py, so the older PRs in this area no longer apply.

One cosmetic note (non-blocking): the /skill slot is reserved unconditionally, so on an install with zero skills the tree maxes at 99 and one extra command that could have fit is dropped. Harmless — the safety invariant (never exceed 100) holds in all cases. Not worth blocking on.

Approving and merging. Thanks for the clean, well-scoped fix and the precise root-cause writeup. 🙏

@kshitijk4poor
kshitijk4poor merged commit cffd6e3 into NousResearch:main Jun 15, 2026
28 checks passed
T02200059 pushed a commit to T02200059/hermes-agent that referenced this pull request Jun 18, 2026
…ommand-100-cap

fix(discord): cap slash commands at Discord's 100-command limit
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…ommand-100-cap

fix(discord): cap slash commands at Discord's 100-command limit
Methodician added a commit to Methodician/hermes-agent that referenced this pull request Jul 4, 2026
…ommand-100-cap

fix(discord): cap slash commands at Discord's 100-command limit
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…ommand-100-cap

fix(discord): cap slash commands at Discord's 100-command limit
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…ommand-100-cap

fix(discord): cap slash commands at Discord's 100-command limit
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…ommand-100-cap

fix(discord): cap slash commands at Discord's 100-command limit
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…ommand-100-cap

fix(discord): cap slash commands at Discord's 100-command limit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists platform/discord Discord bot adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants