Most voice agent issues fall into one of six categories: the button not appearing in the widget, calls connecting but immediately dropping, API key permission errors, transcripts not being recorded, browser-level WebRTC errors, and HTTP-only deployments that block microphone access. Work through the accordion for whichever symptom you are seeing.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/jAtInn71/chatwoot-costom/llms.txt
Use this file to discover all available pages before exploring further.
Call button doesn't appear in the widget
Call button doesn't appear in the widget
Call connects then disconnects in ~3 seconds
Call connects then disconnects in ~3 seconds
A call that connects and then drops within a few seconds almost always means the ElevenLabs account has exhausted its Conversational AI quota.Steps to resolve:
- Open elevenlabs.io/app/usage and check your Conversational AI minutes used.
- The free tier provides approximately 15 minutes of Conversational AI per month. Once exhausted, new calls connect briefly but the ElevenLabs server closes the session immediately.
- Upgrade your ElevenLabs plan or wait for the monthly quota to reset.
"missing_permissions: convai_write" in Rails logs
"missing_permissions: convai_write" in Rails logs
This error appears when an API key is stored on the inbox but it does not have the correct ElevenLabs permission scope.Steps to resolve:
- In the ElevenLabs dashboard, locate the API key you pasted into Chatwoot.
- Edit the key and enable the ElevenAgents → Write permission (
convai_write). - Save the key in ElevenLabs.
- Re-paste the key into the Chatwoot dashboard (Settings → Inboxes → <your inbox> → Configuration → Voice Agent → API Key) and click Save Voice Agent Settings.
For public ElevenLabs agents you do not need an API key at all. Leave the API Key field blank and set the agent’s Security tab to Allow public access in ElevenLabs. The
convai_write permission error only occurs when a key is present but is missing the required scope.Voice transcript not appearing in conversation
Voice transcript not appearing in conversation
If a call completes but no messages appear in the Chatwoot conversation, the POST to
voice_transcript may be failing silently.Steps to resolve:-
Tail the Rails logs while making a test call:
-
A successful transcript POST logs nothing at info level and returns HTTP 200. If you see a
[VOICE-AGENT] voice_transcript failed:line, the error message that follows it identifies the root cause (most often a database constraint or a missing contact/inbox association). -
Check the browser console for
[VOICE-AGENT] transcript post failed:warnings from the widget side. A 401 suggests thewebsite_tokenis wrong or missing; a 422 suggests thesourceorcontentfield was rejected. -
Confirm the ElevenLabs agent is actually firing turn events. Open browser DevTools, go to the Console tab, and look for custom events from the
<elevenlabs-convai>element during an active call. If no events fire, the agent may be configured to suppress transcripts or the SDK version does not emit the expected event names.
Browser shows "WebRTC negotiation timed out"
Browser shows "WebRTC negotiation timed out"
This error was caused by a LiveKit protocol mismatch between the
@elevenlabs/client npm package (which negotiates protocol=17) and ElevenLabs’ production LiveKit server (which is still on protocol 16). The current implementation already avoids this by using the <elevenlabs-convai> CDN embed, which ships its own older LiveKit build that speaks protocol 16.If you see this error:-
It likely means the widget bundle is stale. Rebuild with:
-
After the build completes, restart the stack:
- Hard-refresh the page that hosts the widget (Ctrl+Shift+R / Cmd+Shift+R) to clear any cached bundle.
https://unpkg.com/@elevenlabs/convai-widget-embed) and verify it is still reachable from the visitor’s browser.Voice features not working on HTTP (non-localhost)
Voice features not working on HTTP (non-localhost)
Browsers require a secure origin (HTTPS or
localhost) before granting microphone access via getUserMedia. On a plain HTTP deployment the browser will silently deny mic permission and the call will fail with a NotAllowedError.Steps to resolve:-
For local development:
http://localhost:3000is treated as a secure origin — no change needed. -
For staging or production: deploy behind HTTPS. The easiest path for quick testing is a tunnel such as ngrok or cloudflared:
Use the
https://URL ngrok provides as yourFRONTEND_URLin.env. - For permanent deployments: configure SSL on your reverse proxy (nginx, Caddy, etc.) or use a managed hosting service that terminates TLS for you.