-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
[Bug]: Discord DM pairing identity mismatch breaks PluralKit users; extractDiscordSessionKind regex missing "direct" peer kind #86332
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Bug type
Logic error (behaviour inconsistent between two code paths in the same function)
Summary
Two DM-handling bugs in the Discord plugin:
PluralKit DM pairing infinite loop. When PluralKit transforms the sender identity, the DM preflight passes the raw gateway
authortohandleDiscordDmCommandDecision(which stores the pairing key) but the access check above it uses the resolvedsenderidentity fromresolveDiscordSenderIdentity. These two identities differ for PK users: the pairing is stored under a Discord user/webhook ID while the ingress resolver looks it up under the PK member UUID. Every inbound DM triggers a fresh pairing challenge — the previously-completed one is never found.extractDiscordSessionKindregex doesn't match thedirectpeer kind. The regex/discord:(channel|group|dm):/inconversation-identity.tsdoesn't matchdiscord:direct:, which is the canonical peer kind used for DM session keys throughout the plugin. Works by coincidence today because downstream=== "dm"checks treat the resultingnullthe same as an unrecognised kind, but a latent fragility.Environment
@openclaw/discord)extensions/discord/src/monitor/message-handler.preflight.ts—resolveDiscordDmPreflightAccessextensions/discord/src/conversation-identity.ts—extractDiscordSessionKindSteps to Reproduce (Bug 1)
dmPolicy: "pairing"and PluralKit integration enabled/pair <code>Steps to Reproduce (Bug 2)
Not user-visible today — verify by inspecting
extractDiscordSessionKind("agent:agentId:discord:direct:123456")returnsnullinstead of"direct".Root Cause (Bug 1)
In
resolveDiscordDmPreflightAccess:resolveDiscordDmCommandAccessresolves the ingress subject viacreateDiscordDmIngressSubject(params.sender), which setsstableId = sender.id(the PK member UUID). The ingress resolver stores pairing records keyed by thatstableId. ButhandleDiscordDmCommandDecisioncreates the pairing record usingparams.author.id(the Discord user/webhook ID). On the next inbound message the ingress resolver looks up the PK member UUID and finds nothing.When PluralKit is not active
params.sender.id === params.author.id, so the bug is invisible.Root Cause (Bug 2)
DM session keys use the
directpeer kind (agent:<id>:discord:direct:<userId>), normalised from legacydminsession-key-normalization.ts. The regex only matcheschannel,group, anddm. It doesn't matchdirect.The three callers of
extractDiscordSessionKindall check for=== "dm"and treatnullthe same way (return null/ skip), so there's no visible breakage today. The fix is still worth making to prevent a future code path from treatingnulldifferently.Impact
dmPolicy: "pairing". Every message triggers a new challenge. Allowlist users may also be affected if PK transforms the identity before the ingress check.Related