Troubleshooting¶
Installation found the wrong vaani¶
The public PyPI project named vaani is unrelated. Delete that environment and
follow the private installation. Use the
private index with first-index; do not use a bare pip install vaani.
Artifact Registry authentication fails¶
Check:
gcloud auth application-default logincompleted for the intended identity;- the identity has Artifact Registry Reader access;
keyringandkeyrings.google-artifactregistry-authare installed;UV_KEYRING_PROVIDER=subprocessis set;- the index username is the fixed value
oauth2accesstoken.
Do not paste an access token into a URL, shell history, image, or log.
./scripts/check reports missing credentials¶
Copy .env.example to .env, then fill every variable required by the
selected preset. A Google service-account variable contains the complete JSON
value unless the preset explicitly declares a file-based variable.
Changing the preset also requires its extras and a regenerated production lock.
The worker does not register¶
Confirm:
LIVEKIT_URL,LIVEKIT_API_KEY, andLIVEKIT_API_SECRETare correct;- the agent name matches the token/dispatch configuration;
./scripts/checkpasses;./scripts/devshows the worker registration before the browser connects;- the selected preset's provider extras are installed.
Browser connection, SIP routing, and agent dispatch are separate. A registered worker does not prove that a trunk routes to it.
The worker reports CERTIFICATE_VERIFY_FAILED¶
Opening the LiveKit URL in a browser only proves that the browser trusts its
HTTPS certificate. The worker uses Python aiohttp to open a secure WebSocket
at /agent, which may use a different CA bundle. Incognito mode does not test
the Python path.
From the generated project root, run the same unauthenticated TLS handshake as
the worker. Replace the hostname with the one in LIVEKIT_URL:
LIVEKIT_TEST_URL="wss://your-project.livekit.cloud/agent" \
backend/.venv/bin/python - <<'PY'
import asyncio
import os
import aiohttp
async def check() -> None:
try:
async with aiohttp.ClientSession() as session:
await session.ws_connect(os.environ["LIVEKIT_TEST_URL"])
except aiohttp.WSServerHandshakeError as error:
print(f"TLS_OK HTTP_{error.status}")
except Exception as error:
print(f"TLS_FAILED {type(error).__name__}: {error}")
asyncio.run(check())
PY
TLS_OK HTTP_401 is expected: the probe has no LiveKit credentials, but TLS
verification succeeded. If it prints TLS_FAILED, retry development with the
CA bundle installed in the generated environment:
If that still fails, a company proxy, antivirus product, or network gateway may be replacing the public certificate. Use the CA bundle approved by that network's administrator. Never disable certificate verification.
The bot does not greet first¶
Check that the Assistant has a non-empty greeting, the preparation hook
returns before its deadline, and the worker receives the participant. If the
greeting uses customer data, test the customer lookup independently and handle
an unknown caller explicitly.
The greeting does not use the customer's name¶
The name must come from @assistant.prepare and the greeting must read it from
call.state:
@assistant.prepare
async def load_customer(call: Call) -> object:
customer = await crm.find_by_phone(call.caller)
return {"name": customer.name}
def greeting_for(call: Call) -> str:
return f"Namaste {call.state['name']} ji."
Also confirm that browser/SIP identity supplies the expected caller number and that test-mode redaction is not replacing prepared state.
Responses are slow¶
Measure end-of-speech → final STT, final STT → first model text, and first model text → first TTS audio separately.
Then verify:
- the runtime is the current approved streaming build;
- the selected preset uses its intended STT mode: batch for
basic-monolingual@1, streaming forbirla-prod-v42@14; - LLM output and TTS are streaming;
- Gemini thinking level, token limits, endpointing, and VAD match the reviewed preset;
- provider clients are reused instead of constructed per turn;
- providers and LiveKit run in the intended region;
- the prompt does not ask for long answers.
Do not implement a second streaming loop in the bot. Fix shared pipeline latency in VAANI or its preset.
Live transcript is empty¶
Confirm participant audio reaches the worker and that the frontend subscribes to LiveKit transcription text streams. The VAANI worker publishes both participant and assistant transcript segments. Check worker errors before changing frontend rendering.
If audio works but text does not, ensure the frontend and VAANI runtime are on
compatible LiveKit versions and the transcript panel is listening for
lk.transcription.
Speech is not understood¶
Confirm the preset's language, Deepgram model, and active language binding. Test with a clean microphone and inspect the participant transcript. If the transcript is wrong, diagnose STT/VAD/noise settings; if it is right but the answer is wrong, diagnose the prompt, model, or tools.
A prompt or language switch fails¶
switch_prompt requires the target name to be registered with
assistant.add_prompt. switch_language requires a complete preset language
binding. Regenerate the production lock after either definition changes.
A transfer fails¶
Register a safe route name with assistant.add_transfer_route, configure its
deployment-owned destination, and test it against an authorized SIP target.
The model never receives the raw destination.
FrozenInstanceError¶
VAANI configuration values are immutable. Construct a new value or use
dataclasses.replace; do not assign fields after construction. An Assistant
also freezes after successful check() or call start, so register prompts,
tools, routes, Judge configuration, and overrides first.
InvalidCallSetup or lock mismatch¶
Read error.issues. Common causes are:
- changed preset without regenerating the lock;
- missing provider extra or credential;
- unsupported language/voice override;
- tool without complete annotations;
- named prompt or transfer route added after the lock was created.
Fix the definition, regenerate the lock, review its diff, and rerun
./scripts/check.
Next: live voice testing or production readiness.