Error Codes & Troubleshooting
Common errors and how to resolve them.
Self-diagnostics (start here)
Before digging into error codes, the dashboard has two buttons that pinpoint where the silence is:
- Test button next to each connected platform (Dashboard → Platforms) — sends a real message to your own account on that platform. If you receive it, Chamade can reach the platform correctly. If not, the error modal shows the specific platform response (Nextcloud 500, Discord DM privacy, Teams no prior chat, WhatsApp 24h window, …).
-
Ping agents button at the top of
(Dashboard → API keys) —
publishes a synthetic DM on your MCP channel and waits up to 30s
for every agent authenticated with one of your keys to reply.
Each key gets a
✓ replied/× no replybadge. Four verdicts:- replied — the loop is wired correctly end-to-end.
- connected but silent — MCP session is live, but your client isn’t reacting to
dm_chatevents. Only Claude Code natively handles push channels; other clients (Cursor, Windsurf, custom) must pollchamade_inbox. - API key used recently but no MCP session — your client doesn’t hold a long-lived session. Keep one HTTP session open or switch to a client that does.
- not connected — no MCP session, no recent API activity. Re-check the key and the client config.
If the diagnosis the dashboard shows seems wrong, each error modal has a Diagnosis wrong? Tell us button that ships the full context to our inbox so we can improve the pattern table.
HTTP Errors
| Error | Cause | Fix |
|---|---|---|
401 Invalid or missing API key |
Missing or incorrect X-API-Key header |
Check your API key in the Dashboard |
404 Call not found |
Call ID does not exist or has ended | Use GET /api/calls to list active calls |
429 Concurrent call limit reached |
Rate limit hit | End an active call first, or retry shortly |
400 Hosted TTS not configured |
Call was created without a TTS preset (or the user has no enabled TTS provider) | Add an ElevenLabs / Deepgram / … TTS provider in dashboard → Voice providers (BYOK — free on Chamade's side), or use BYO audio on the call WebSocket |
Platform Errors
| Error | Cause | Fix |
|---|---|---|
400 No discord bot registered |
No Discord bot token in dashboard | Add a Discord bot token in Dashboard → My Bots, or connect the shared bot via Dashboard → Platforms |
400 No telegram bot registered |
No Telegram bot token in dashboard | Add a Telegram bot token in Dashboard → My Bots |
400 meeting_url required |
No meeting URL provided and no OAuth connected | Provide a meeting URL, or connect your account via OAuth in the Dashboard |
400 No SIP trunk configured |
Trying outbound SIP without a trunk | Connect a SIP trunk in Dashboard → SIP |
409 No active WebSocket connection |
Bridge connection not ready yet | Wait a moment for the connection to establish |
File Upload & Serve Errors
| Error | Cause | Fix |
|---|---|---|
413 File exceeds max size (N bytes) |
Upload larger than 25 MB (default CHAMADE_FILES_MAX_SIZE_MB) |
Compress / resize, or split into multiple attachments. Chamade enforces the cap while streaming so a 25 MB+1-byte upload fails instantly rather than committing memory. |
400 Provide exactly one of url or bytes_b64 |
Both set, or both missing, on POST /api/files JSON body |
Send exactly one of the three shapes: multipart file, JSON {url}, or JSON {bytes_b64, name, mime}. |
400 Invalid URL / SSRF blocked |
POST /api/files {url} pointing at a private IP (RFC1918, loopback, link-local, AWS/GCP metadata) |
Host the file on a publicly reachable URL, or upload the bytes directly via multipart. |
403 File belongs to another user |
Passing an attachments: [{file_id}] created by a different Chamade account |
Upload the file under your own API key first. File IDs are user-scoped. |
404 Unknown file token |
Token invalid, expired (24 h for uploads), or the pre-signed upload slot was already consumed | Mint a fresh slot via POST /api/files/reserve and re-upload. |
410 Gone (on GET /api/files/{token}) |
The upstream platform has evicted the file (WhatsApp drops at ~30 days, Discord CDN signed URLs expire, etc.) | Expected — Chamade never persists bytes long-term. If you need long-term storage, re-upload the file via POST /api/files from your agent. |
415 / inbound attachment skipped with [attachment too large] |
Inbound attachment exceeds 25 MB cap | Chamade falls back to a text stub in the inbox. Ask the user to re-send a smaller file or send a link. |
Message Delivery Errors
| Error | Cause | Fix |
|---|---|---|
502 Failed to send message |
The platform rejected the message (too long, rate limited, formatting error, invalid chat) | Check the message length against the platform limit. Shorten the message or split it into multiple calls. |
404 No active conversation |
No active DM conversation on the specified platform | The user must send a message first to start a conversation. Check chamade_inbox for active conversations. |
Recovery from Disconnection
If the bridge restarts or the connection is lost, the call state becomes "disconnected". The chamade_call_status tool (or GET /api/call/{id}) will indicate this.
To recover: call chamade_call_join (or POST /api/call) again with the same platform and meeting URL. A new call ID is issued. The previous transcript is not carried over.
If your agent polls chamade_call_status regularly, it will detect disconnections automatically and can reconnect without user intervention.
