| title | Common Issues |
|---|---|
| description | Solutions for the most frequent discli problems |
The most frequent problems people encounter with discli, with symptoms, causes, and fixes.
``` Error: No bot token found. Set via `discli config set token`, --token flag, or DISCORD_BOT_TOKEN env var. ```Cause: discli checks three places for your bot token, in order: the --token CLI flag, the DISCORD_BOT_TOKEN environment variable, and ~/.discli/config.json. If none of them have a token, you get this error.
Fix:
# Option 1: Save it permanently
discli config set token YOUR_BOT_TOKEN
# Option 2: Set it for the current session
export DISCORD_BOT_TOKEN=YOUR_BOT_TOKEN
# Option 3: Pass it per-command
discli --token YOUR_BOT_TOKEN message send "#general" "hello"Error: Action "channel_delete" is not allowed by profile "safe-agent".
Cause: You are running with a permission profile that restricts the command you are trying to use.
Fix:
# See what the current profile allows
discli permission show safe-agent
# Switch to a different profile
discli serve --profile admin
# Or run without a profile (all actions allowed)
discli serveSymptom: Your bot is online (green dot in Discord) but ignores all messages. discli listen --events messages produces no output.
Cause: The MESSAGE_CONTENT privileged intent is not enabled for your bot.
Fix:
Open [discord.com/developers/applications](https://discord.com/developers/applications) and select your bot. Navigate to **Bot** > **Privileged Gateway Intents** > enable **Message Content Intent**. The intent change takes effect on the next gateway connection. Restart `discli serve` or `discli listen`.Error: Rate limited. Retry after 2.5s.
Cause: Either Discord's API rate limiter or discli's built-in rate limiter has been triggered. discli enforces a default limit of 5 destructive actions per 5 seconds to protect your bot from accidental spam.
Fix:
- Reduce frequency — space out your actions, especially bulk sends
- Check your code — an infinite loop or missing deduplication can cause rapid-fire requests
- For Discord 429s — discli retries automatically with backoff. If you see persistent 429s, you are sending too much traffic
Symptom: You run discli listen --events messages and the process starts but no events appear, even when messages are sent in the server.
Cause: The GUILD_MESSAGES intent is not enabled, or the bot does not have permission to view the channel.
Fix:
- Enable Server Members Intent and Message Content Intent in the Developer Portal (see above)
- Verify the bot has View Channel and Read Message History permissions in the target channel
- Check that the bot is actually in the server —
discli server listshould show it
Symptom: discli serve starts and then exits within a few seconds, sometimes with no output.
Cause: Usually an invalid token, network connectivity issue, or missing intents.
Fix:
# Check stderr for error details
discli serve 2> error.log
cat error.log
# Verify your token works
discli server list
# Check network connectivity
discli config showSymptom: You registered slash commands but they do not show up in Discord's command picker.
Cause: Global slash commands can take up to 1 hour to propagate across Discord. This is a Discord limitation, not a discli issue.
Fix:
- Wait up to 1 hour for global commands to sync
- Use guild-specific commands for testing — they sync instantly:
# Guild-specific (instant)
discli slash register --guild 1234567890 --name ping --description "Pong!"
# Global (up to 1 hour delay)
discli slash register --name ping --description "Pong!"Error: Unknown channel "general". Did you mean "#general"?
Cause: Channel names must be prefixed with # so discli knows you are referencing a channel name, not a server name.
Fix:
# Wrong — discli interprets this as a server name
discli message send general "hello"
# Right — the # prefix identifies it as a channel
discli message send "#general" "hello"
# Also right — raw numeric IDs need no prefix
discli message send 1234567890123456789 "hello"Symptom: discli message list "#general" works fine, but discli message send "#general" "hello" returns a permission error.
Cause: The bot has View Channel and Read Message History permissions but is missing Send Messages.
Fix:
- Open Server Settings > Roles in Discord
- Find your bot's role
- Enable the Send Messages permission
- If the channel has permission overrides, check those too — channel-level permissions override role permissions
Symptom: Running any discli voice command exits immediately with:
Error: Voice features need extras that aren't installed: PyNaCl, discord-ext-voice-recv, davey.
Install with: uv sync --extra voice (or: pip install 'discord-cli-agent[voice]').
Run `discli doctor` to verify the full setup.
Cause: The voice optional dependencies aren't installed. discli's core install is text-only to keep dependency footprint small.
Fix:
pip install 'discord-cli-agent[voice,deepgram]'
# or, in a checkout:
uv sync --extra voice --extra deepgramThen verify:
discli doctorSymptom: discli voice listen (or the meeting transcriber example) connects, prints Listening to #..., but no transcript lines ever appear no matter how loud anyone speaks.
Possible causes and fixes:
- No STT key set. Run
discli doctor— ifDEEPGRAM_API_KEY(or your provider's key) is not set, set it and restart. - Bot is server-deafened. Discord lets server admins deafen bots — check the channel members list and right-click the bot to confirm it isn't muted/deafened server-side.
- DAVE patch failed to install.
discli doctorshould show[ok] DAVE/Opus patches. If it shows[FAIL], the listener can't decrypt audio. File an issue with the doctor output. - Audio is reaching the bot but STT is rejecting it. Run
discli voice capture --duration 10while someone speaks. If the WAV file is non-empty and plays back as real audio, capture works and the issue is downstream (STT key, network, provider quota). If the WAV is empty or only ~20ms long, capture itself is broken — file an issue.
Symptom: Logs show repeated OpusError('corrupted stream') lines, transcripts are empty or sporadic.
Cause: Discord's voice transport uses DAVE (end-to-end voice encryption). The off-the-shelf discord-ext-voice-recv library doesn't decrypt DAVE, so libopus sees still-encrypted bytes and rejects them. discli ships a runtime monkeypatch that calls davey.DaveSession.decrypt(...) between the SecretBox layer and libopus.
If the patch is installed correctly you should still see occasional [voice] skipping bad opus packet lines (a few per session is normal — those are out-of-order or corrupt-on-the-wire frames). If you see hundreds, the patch isn't taking effect.
Fix:
discli doctorConfirm DAVE/Opus patches reports [ok]. If it doesn't, your davey install is broken — reinstall the voice extra:
pip install --force-reinstall 'discord-cli-agent[voice]'Symptom: discli doctor exits with N problem(s) found.
Fix: Each failed line has a hint: underneath. Follow those — they list the exact install command or env var for the specific dependency. --json output gives the same structured data for scripting:
discli doctor --json | jq '.sections[].checks[] | select(.ok==false)'