Summary
Discord threads bound to OpenClaw sessions can mis-handle PluralKit messages as duplicate inbound turns.
Observed behavior in a live Discord thread:
- only one visible reply is eventually sent
- but the agent can behave as if it saw duplicate inbound context
- and a lingering typing indicator can appear after the reply for PluralKit-routed messages but not for normal Discord messages
Expected behavior
A PluralKit-originated message in a bound Discord thread should behave like a single inbound turn:
- one canonical inbound event
- one run
- one reply
- no extra typing / queue wobble
Likely cause
PluralKit introduces an additional webhook-authored copy of the user message. In bound Discord threads, the original message and the proxied webhook copy can both influence the inbound pipeline.
The issue appears to have two layers:
- bound-thread webhook suppression was too narrow and primarily targeted the bound OpenClaw webhook echo
- generic inbound dedupe uses message ids, so original + proxied copies with different ids can still both exert turn pressure
That leaves room for:
- duplicate context bleed
- second-run wobble
- typing indicator side effects even when only one reply is ultimately visible
Fix direction
This patch takes a layered approach:
- broaden bound-thread webhook suppression so webhook-authored copies in already-bound threads are ignored more aggressively
- add a short-lived Discord bound-thread content-clone dedupe fallback for agent-session routes to collapse original/proxy pairs with different message ids
- suppress Discord typing for PluralKit-originated bound-thread turns so ghost duplicate pressure does not leak as a typing indicator
The content-clone dedupe is intentionally narrow:
- Discord only
- thread only
- agent-session scope only
- short TTL (15s)
Notes
The content-clone dedupe is a fallback safety net, not the ideal canonicalization mechanism. If there is a better explicit Discord/PluralKit signal available earlier in the pipeline, that would be preferable as a long-term refinement.
Repro shape
- create a Discord thread bound to an OpenClaw session
- enable Discord PluralKit integration
- send into the thread through PluralKit
- compare behavior with a normal non-PluralKit Discord message in the same thread
Validation
Focused tests added/updated for:
- bound-thread webhook suppression behavior
- Discord inbound content-clone dedupe fallback
- Discord process-path typing behavior regression coverage
Summary
Discord threads bound to OpenClaw sessions can mis-handle PluralKit messages as duplicate inbound turns.
Observed behavior in a live Discord thread:
Expected behavior
A PluralKit-originated message in a bound Discord thread should behave like a single inbound turn:
Likely cause
PluralKit introduces an additional webhook-authored copy of the user message. In bound Discord threads, the original message and the proxied webhook copy can both influence the inbound pipeline.
The issue appears to have two layers:
That leaves room for:
Fix direction
This patch takes a layered approach:
The content-clone dedupe is intentionally narrow:
Notes
The content-clone dedupe is a fallback safety net, not the ideal canonicalization mechanism. If there is a better explicit Discord/PluralKit signal available earlier in the pipeline, that would be preferable as a long-term refinement.
Repro shape
Validation
Focused tests added/updated for: