fix(discord): delete obsolete slash commands before creating (avoid 100-cap error 30032) - #50992
Merged
Conversation
Add a test to verify that _safe_sync_slash_commands deletes obsolete commands before creating new ones. This ensures we never temporarily exceed Discord's 100-command limit during sync, which would trigger error 30032 and break all slash commands. This test guards against the regression where sync could fail even though the registration cap was properly enforced.
Discord enforces a hard 100-command limit per app and rejects an upsert that would push the live total over 100 (error 30032), which silently breaks ALL slash commands. The sync deleted obsolete commands AFTER creating new ones, so an app already at the cap momentarily exceeded it and the whole sync failed. Reorder: delete no-longer-desired commands up front, then create/update. Removes the now-redundant trailing delete loop. Adapts @infinitycrew39 PR #50890 to current main (the original adapter diff no longer applied after the platform refactor); test commit cherry-picked with authorship preserved.
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
invalid-assignment |
4 |
unresolved-attribute |
2 |
unresolved-import |
1 |
First entries
tests/gateway/test_discord_sync_limit.py:85: [invalid-assignment] invalid-assignment: Object of type `MagicMock` is not assignable to attribute `_patchable_app_command_payload` of type `def _patchable_app_command_payload(self, payload: dict[str, Any]) -> dict[str, Any]`
run_agent.py:2984: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
tests/gateway/test_discord_sync_limit.py:84: [invalid-assignment] invalid-assignment: Object of type `MagicMock` is not assignable to attribute `_canonicalize_app_command_payload` of type `def _canonicalize_app_command_payload(self, payload: dict[str, Any]) -> dict[str, Any]`
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
tests/gateway/test_discord_sync_limit.py:7: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/gateway/test_discord_sync_limit.py:82: [invalid-assignment] invalid-assignment: Object of type `AsyncMock` is not assignable to attribute `_sleep_between_command_sync_mutations` of type `def _sleep_between_command_sync_mutations(self) -> CoroutineType[Any, Any, None]`
tests/gateway/test_discord_sync_limit.py:83: [invalid-assignment] invalid-assignment: Object of type `MagicMock` is not assignable to attribute `_existing_command_to_payload` of type `def _existing_command_to_payload(self, command: Any) -> dict[str, Any]`
✅ Fixed issues (1):
| Rule | Count |
|---|---|
invalid-assignment |
1 |
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`
Unchanged: 6027 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
Collaborator
|
Duplicate of #46078 (merged) — the root-cause fix already caps the desired command set at 100, so the live total can't exceed the cap mid-sync. The delete-before-create reorder here is the band-aid approach already covered by that cluster (#40699, #28800, #29134, #24371, #19366). This PR is a salvage of #50890 (@infinitycrew39). Marking duplicate of the canonical merged fix. |
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.
Summary
Discord slash-command sync no longer fails with error 30032 ("ALL slash commands broken") when an app at the 100-command cap needs a new command.
Discord enforces a hard 100-command limit per app and rejects an upsert that would push the live total over 100. The sync created new commands before deleting obsolete ones, so an app already at the cap momentarily reached 101 mid-sync and the whole operation was rejected — silently disabling every slash command. This is the second, separate error visible later in NilVaw's cron log (the first being the cron RuntimeError, fixed in #50989).
Changes
plugins/platforms/discord/adapter.py: computeobsolete_keys = existing − desiredand delete them first, then run the create/update loop. Removes the now-redundant trailing delete loop. The live total never rises above the cap mid-sync.Validation
tests/gateway/test_discord_sync_limit.py(new regression test asserting deletions precede creations) +tests/gateway/test_discord_connect.py→ all passing.Salvage of #50890 by @infinitycrew39 — the regression test cherry-picked with authorship preserved; the adapter reorder re-applied to current
main(the original adapter diff no longer applied after the platform refactor) under maintainer authorship. Reported by NilVaw in Discord.Infographic