fix(discord): delete obsolete slash commands before creating new ones

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.
This commit is contained in:
Teknium 2026-06-22 12:20:28 -07:00
parent 91c465f6e7
commit e9b86f352f

View file

@ -1590,6 +1590,19 @@ class DiscordAdapter(BasePlatformAdapter):
mutation_count += 1
return result
# Delete obsolete commands FIRST to stay under Discord's 100-command
# limit. Discord rejects an upsert that would push the live total over
# 100 (error 30032), which silently breaks ALL slash commands. If a new
# command is created before the obsolete ones are removed, an app that
# is already at the cap momentarily exceeds it and the whole sync fails.
# Removing the no-longer-desired commands up front guarantees the live
# total never rises above the cap mid-sync.
obsolete_keys = set(existing_by_key.keys()) - set(desired_by_key.keys())
for key in obsolete_keys:
current = existing_by_key.pop(key)
await mutate(http.delete_global_command, app_id, current.id)
deleted += 1
for key, desired in desired_by_key.items():
current = existing_by_key.pop(key, None)
if current is None:
@ -1613,10 +1626,6 @@ class DiscordAdapter(BasePlatformAdapter):
await mutate(http.edit_global_command, app_id, current.id, desired)
updated += 1
for current in existing_by_key.values():
await mutate(http.delete_global_command, app_id, current.id)
deleted += 1
return {
"total": len(desired_payloads),
"unchanged": unchanged,