Discord skills (/discord:configure, /discord:access) hardcode ~/.claude/channels/discord/ path — ignores DISCORD_STATE_DIR

Author: ChinzziiCreated Apr 3, 2026Updated Sep 16, 2026

Summary

The Discord plugin's server.ts correctly reads DISCORD_STATE_DIR to resolve state directory, token, and access.json. But the skill files that Claude reads when executing /discord:configure and /discord:access hardcode ~/.claude/channels/discord/ — so Claude reads/writes the wrong files when DISCORD_STATE_DIR is set.

Related: #865

Exact location of the bug

external_plugins/discord/skills/configure/SKILL.md

  • Hardcodes ~/.claude/channels/discord/.env for token read/write
  • Claude follows this literally, ignoring DISCORD_STATE_DIR

external_plugins/discord/skills/access/SKILL.md

  • Hardcodes: "All state lives in ~/.claude/channels/discord/access.json"
  • All subcommands (pair, allow, deny, remove, policy, group, set) read/write to this hardcoded path

Meanwhile, server.ts correctly resolves the path:

javascript
const STATE_DIR = process.env.DISCORD_STATE_DIR ?? join(homedir(), '.claude', 'channels', 'discord')
const ACCESS_FILE = join(STATE_DIR, 'access.json')
const ENV_FILE = join(STATE_DIR, '.env')

The plugin connects to Discord using the right token and access.json from DISCORD_STATE_DIR. But the skills tell Claude to look elsewhere.

Reproduction

  1. Set up two bots on one machine with separate state dirs:
bash
# Bot 1
DISCORD_STATE_DIR=/path/to/.bots/bot1 claude --channels plugin:discord@claude-plugins-official

# Bot 2
DISCORD_STATE_DIR=/path/to/.bots/bot2 claude --channels plugin:discord@claude-plugins-official
  1. Both bots connect to Discord correctly (plugin reads DISCORD_STATE_DIR)

  2. Run /discord:configure in either session — shows "Token: Not set" and "0 senders" because it reads ~/.claude/channels/discord/ instead of $DISCORD_STATE_DIR

  3. Run /discord:access pair <code> — writes to ~/.claude/channels/discord/access.json instead of $DISCORD_STATE_DIR/access.json. Plugin never sees the pairing.

Impact

Running 3 bots from one machine with separate DISCORD_STATE_DIR paths:

  • /discord:configure shows "Token: Not set" even though the bot is connected and responding
  • /discord:access pair <code> writes to the global file — plugin never sees it
  • Must manually write access.json to the correct state dir as a workaround
  • Confusing UX: plugin works, skills report it's broken

Suggested fix

In both SKILL.md files, replace hardcoded paths with env-aware resolution:

State directory: use $DISCORD_STATE_DIR if set, otherwise ~/.claude/channels/discord/
Token: {state_dir}/.env
Access: {state_dir}/access.json

Or expose the resolved STATE_DIR as an MCP resource so the skills can query the actual path the plugin is using.

Environment

  • Claude Code v2.1.87
  • Discord plugin from claude-plugins-official (main branch)
  • Ubuntu 22.04, 3 bot instances on one Linux user with separate DISCORD_STATE_DIR

Source: anthropics/claude-plugins-official