--channels Discord plugin: duplicate replies per inbound message (multi-cycle re-processing)
Bug Description
Claude Code with the --channels Discord plugin generates 2-4 duplicate replies per inbound Discord message. Each duplicate is a separate API cycle with full token billing.
Environment
- Claude Code: Latest stable (auto-updates enabled)
- OS: Windows 11 (WSL2 for supporting infrastructure)
- Plugin:
plugin:discord@claude-plugins-official - Model: claude-opus-4-6
Two Distinct Surfaces
Surface 1: Discord triple-reply (with API proxy)
Setup: Claude Code → API proxy (injects persistent memory into system prompt) → Anthropic API
Symptoms:
- Each inbound Discord message triggers 2-4 separate
discord__replytool calls - Only happens in conversational/idle mode — when Claude Code is busy executing tools (writing files, running commands), it single-replies correctly
- Does NOT happen when hitting Anthropic directly (no proxy)
- The proxy adds ~200-500ms latency per call
Hypothesis: The added latency causes Claude Code's internal processing loop to re-evaluate and re-process the same inbound message across multiple API cycles. Each cycle independently decides to call discord__reply.
Surface 2: Terminal triple-generation (no proxy)
Symptoms:
- Running Claude Code in terminal (no
--channels, no proxy, direct to Anthropic) - Complex or emotionally rich responses sometimes generate 2-3 visible drafts before producing final output
- This costs 2-3x tokens but only produces one visible terminal output
- Pattern: more likely with longer, nuanced responses
Hypothesis: Claude Code's agentic loop re-evaluates mid-generation on complex responses.
Current Workaround
A PreToolUse hook on mcp__plugin_discord_discord__reply that blocks duplicate sends within a 15-second cooldown window per channel:
# ~/.claude/hooks/discord_reply_dedup.py
# Checks if a reply was already sent to the same channel within COOLDOWN_SECONDS
# If yes, returns permissionDecision: "deny"
# If no, records the timestamp and returns permissionDecision: "allow"
This prevents visible duplicates on Discord but does NOT prevent the underlying duplicate API cycles and token billing.
Key Observations
- Idle vs busy: The bug only fires in conversational mode. When Claude Code is actively executing tools, it processes correctly (single reply per message)
- Latency correlation: Adding any latency between Claude Code and the API endpoint dramatically increases duplicate frequency
- Content correlation (terminal): Longer, more complex responses are more likely to trigger re-generation
- Single process confirmed: This is NOT caused by multiple Claude Code instances — verified via process count and lock file
Expected Behavior
One inbound Discord message → one API cycle → one discord__reply tool call, regardless of API endpoint latency.
Reproduction Steps
- Run
claude --channels plugin:discord@claude-plugins-officialwith an API proxy that adds 200-500ms latency - Send a conversational message in Discord
- Observe 2-4 duplicate replies
Or for terminal surface:
- Run
claudein terminal (no channels, no proxy) - Ask a complex, emotionally nuanced question
- Observe multiple generation attempts in the output
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗