Skip to content

fix(events): prevent double slash/component execution on interactionCreate#125

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-correctness-bugs-0128
Draft

fix(events): prevent double slash/component execution on interactionCreate#125
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-correctness-bugs-0128

Conversation

@cursor

@cursor cursor Bot commented Jun 14, 2026

Copy link
Copy Markdown

Bug and impact

Slash commands, dev commands, buttons, select menus, and modals were executed twice on every interaction. Validators (src/events/validations/*) and Guild handlers (interactionCreate.js, components.js) each registered separate client.on("interactionCreate") listeners. Because Discord.js invokes listeners concurrently, both paths could pass interaction.replied checks before either replied.

Concrete trigger: A user runs /deposit amount:100. Both chatInputCommandValidator and Guild/interactionCreate call command.run(), applying two deposits and attempting two replies (second throws or is swallowed).

Same pattern affected /rob (economy corruption), ticket buttons, and dev commands like /eval.

Root cause

The events handler regression fix restored per-module Guild listeners without deduplicating the existing validations listener chain. The prior replied/deferred guards only worked within a single listener, not across parallel listeners.

Fix

  • Register one interactionCreate listener that runs validators → components.runinteractionCreate.run sequentially.
  • Skip registering Guild interactionCreate.js / components.js as separate listeners.
  • Validators now perform permission gating only; execution happens once in the Guild handlers.
  • Context menus still execute in contextMenuCommandValidator (no duplicate Guild handler exists).

Validation

  • Added tests/interaction-single-listener.test.js regression tests.
  • Updated tests/events-handler-shape.test.js.
  • npm test — 40/40 passing.
Open in Web View Automation 

…reate

Validators and Guild handlers each registered separate interactionCreate
listeners. Both could run the same command before either replied, causing
duplicate economy mutations, double replies, and cooldown bypass.

Chain validators, components, and interactionCreate in one sequential
listener. Validators now gate permissions only; Guild handlers execute once.

Co-authored-by: zVapor_ <contact@zvapor.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant