[BUG] Discord Channels Plugin DM bug
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Discord plugin: DM routing fails after Claude Code restarts; approved/ directory wiped on update
Two related problems in the discord plugin (v0.0.4) that together make DM routing unreliable in long-running deployments.
---
Issue 1: DM routing silently fails after Claude Code/plugin restart
After Claude Code restarts (e.g. auto-update), the MCP reply tool fails for DM channels with:
reply failed: channel <dm_channel_id> is not allowlisted — add via /discord:access
This occurs even when the sender's user ID is correctly listed in access.json → allowFrom.
Root cause (from server.ts): when the Discord.js client restarts and fetches a DM channel cold, ch.recipientId is null — the gateway hasn't delivered the channel object yet. The allowFrom check fails even though the user is correctly listed.
Workaround: use the Discord REST API directly (POST /channels/{id}/messages) — stateless, always works.
Suggested fix: pre-populate the DM channel cache on startup for all allowFrom user IDs, or fall back to a user ID lookup when recipientId is null.
Issue 2: approved/ directory wiped on Claude Code auto-update; no idempotency on pairing ceremony
The ~/.claude/channels/discord/approved/ directory is deleted when Claude Code auto-updates and reinitializes the plugin.
Secondary issue: any attempt to recreate a file in approved/<senderId> to restore routing causes checkApprovals() to fire "Paired! Say hi to Claude." again — no idempotency check exists. The poll-and-delete loop treats every new file as a fresh pairing ceremony. In a long-running deployment with automation watching for the missing file, this results in the pairing message firing on every poll cycle.
Suggested fixes:
- Persist the
approved/directory across updates (treat as user state, not plugin ephemeral state) - Or separate the routing map from the pairing ceremony trigger — store confirmed DM mappings in
access.jsonunder admChannelskey, and only send "Paired!" on genuinely new pairings
---
Environment
- Plugin: discord v0.0.4
- Deployment: long-running always-on instance, Claude Code auto-updates enabled
- No custom plugin modifications
What Should Happen?
DM channel with approved users should stay accessible to the agent across updates to the client, even in a persistent tmux terminal session.
Error Messages/Logs
Steps to Reproduce
Tmux code session - auto update client on pi.
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.83
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗