gentle-church-5117
04/21/2026, 5:18 PMrawData: {
"type": "final_transcript",
"session_id": "83f21820-bc4c-4180-90dd-7356d976e764",
"transcript": "",
"start": 6.236,
"duration": 15,
"confidence": 1,
"words": null,
"language": "es",
"extra": null
}
error: {
"type": "ZodError",
"message": "[\n {\n \"expected\": \"array\",\n \"code\": \"invalid_type\",\n \"path\": [\n \"words\"\n ],\n \"message\": \"Invalid input: expected array, received null\"\n }\n]",
"stack":
ZodError: [
{
"expected": "array",
"code": "invalid_type",
"path": [
"words"
],
"message": "Invalid input: expected array, received null"
}
]
at new ZodError (file:///Users/carloslostao/Eighteen/realtie/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.js:39:39)
at Module.<anonymous> (file:///Users/carloslostao/Eighteen/realtie/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/parse.js:53:20)
at inst.safeParseAsync (file:///Users/carloslostao/Eighteen/realtie/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/schemas.js:42:57)
at recv (/Users/carloslostao/Eighteen/realtie/node_modules/.pnpm/@livekit+agents@1.2.0_@livekit+rtc-node@0.13.24_zod@4.3.6/node_modules/@livekit/agents/src/inference/stt.ts:502:60)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async run (/Users/carloslostao/Eighteen/realtie/node_modules/.pnpm/@livekit+agents@1.2.0_@livekit+rtc-node@0.13.24_zod@4.3.6/node_modules/@livekit/agents/src/utils.ts:501:14)
"name": "ZodError"
}
This basically means that until the user generates an "interruption," the agent doesn't restart to be available. It basically stays silent for a long time, like eight seconds or more eventall-airline-16756
04/21/2026, 5:18 PMtall-airline-16756
04/21/2026, 5:18 PMwords is null (the schema expects an array), and that coincides with the agent staying silent until an interruption. I can help troubleshoot this.
Could you tell me:
1. Which version of @livekit/agents are you running? (from package.json or pnpm ls @livekit/agents)
2. Which STT provider/adapter are you using (built-in LiveKit, Whisper, Google, etc.)?
3. Is the empty `transcript`/`words: null` happening for short utterances or long silences? Any audio examples or a description of what the speaker did?
4. Do you have custom code that transforms the STT response before it reaches `recv`/the Zod parse? If so, can you paste the handler (relevant lines around the call in stt.ts:502)?
5. Do you want the agent to emit a partial empty transcript (and keep listening) or to restart immediately on empty results?
With those details I’ll suggest a short-term workaround (schema-tolerant parsing or mapping null→[]), and the best long-term fix.
, with interactive elementsgentle-church-5117
04/21/2026, 5:22 PM(base) carloslostao@MacBook-Pro-3 livekit % pnpm ls @livekit/agents
Legend: production dependency, optional only, dev only
@realtie/livekit@1.0.0 /Users/carloslostao/Eighteen/realtie/livekit (PRIVATE)
dependencies:
@livekit/agents 1.2.0
2. I'm using Livekit's auto STT
stt: new inference.STT({
model: 'auto',
language: 'es',
modelOptions: { keyterms: KEYTERMS },
}),
3. I'm not sure
4. No STT transformations
5. I want that the agent doesn't get stalled being the user incharge of retaking the convtall-airline-16756
04/21/2026, 5:22 PMinference.STT with model: 'auto', no custom transforms). You’re seeing a ZodError because the STT output includes "words": null while the agent expects an array, and that empty-final result is causing a perceived stall until the next interruption.
What you can do now:
1. Prevent automatic resume after a false interruption so the agent doesn’t stay stuck trying to process an empty transcript. Set turn handling interruption options when you create the agent session:
turnHandling: {
interruption: {
falseInterruptionTimeout: 2000, // adjust ms as desired
resumeFalseInterruption: false, // do not auto-resume on empty results
},
},
This makes the agent wait for the user to continue instead of restarting automatically.
1. Add a tolerant parsing/workaround for words: null to avoid the Zod failure (short-term). Before the parse that raises the ZodError, normalize null → [] for the words field so the schema validation succeeds:
if (rawData.words == null) rawData.words = [];
// then call the existing parse/safeParse
You said you have no STT transforms now, so add this small check near where `recv`/the Zod parse is invoked (around stt.ts:502 in your stack trace).
If you want, I can:
• Suggest an exact patch location/snippet for your current @livekit/agents v1.2.0 code (pointing to lines around recv in stt.ts).
• Recommend values for falseInterruptionTimeout based on how long you want the agent to wait.
Which would you prefer?
Sources: Speech-to-text (STT) models overview | LiveKit Documentation | Deepgram STT | LiveKit Documentation | Turns overview | LiveKit Documentation, with interactive elementsgentle-church-5117
04/21/2026, 5:24 PMfalseInterruptionTimeouttall-airline-16756
04/21/2026, 5:24 PMfalseInterruptionTimeout.
Considerations
• Typical user pause length: Measure how long users naturally pause when speaking in your app (short answers vs. long thinking). Timeout should be longer than common short pauses.
• Desired responsiveness: Shorter timeout → agent resumes faster after real interruptions; longer timeout → fewer false resumptions from brief silences.
• STT/Network latency: If STT or network adds delay before final transcripts arrive, allow extra buffer so you don’t treat delayed results as interruptions.
• False-interruption frequency: If you see many empty/ null transcripts, prefer a longer timeout or disable auto-resume (set resumeFalseInterruption: false) and rely on user action.
• Conversation style: For fast back-and-forth (chatty) flows pick shorter time; for reflective or multi-party talk pick longer time.
• UX trade-offs: Short time risks cutting off users mid-thought; long time can make the agent seem unresponsive.
Practical guidance
• Start with 1500–3000 ms (1.5–3s) for typical conversational apps.
• If users often pause briefly, increase toward 3–5s.
• If you see STT latency or many empty transcripts, either increase timeout or set resumeFalseInterruption: false.
• Test with real usage and iterate: run with telemetry (measure how often timeouts trigger and whether they’re true/false interruptions) and adjust.
Example:
• Fast-interaction app: 1200–2000 ms.
• General-purpose conversational app: 2000–3000 ms.
• Reflective/long-pause scenarios: 3000–5000 ms or disable auto-resume.
If you’d like, tell me the typical user flow (short replies vs. long monologues) and I’ll recommend a starting value for your case.
, with interactive elementsgentle-church-5117
04/21/2026, 6:10 PMtall-airline-16756
04/21/2026, 6:11 PM"no", "sí") so the STT model boosts those tokens. With model: 'auto' this may or may not be supported by the selected backend, but it’s safe to pass via modelOptions.keyterms (you already have KEYTERMS)—add the short responses you care about.
2) Lower the VAD/endpoint thresholds so short utterances aren’t cut off
• Reduce min_interruption_duration (or provider equivalent such as min_speech_duration_ms) to ~100–200 ms so very brief speech can trigger transcription.
• Ensure min_interruption_words is 0 or 1 so one-word replies are accepted.
3) Tune false-interruption handling together with VAD
• Keep falseInterruptionTimeout moderate (1.5–3s) and set resumeFalseInterruption: false if you prefer the user to control resuming. This avoids auto-resume behavior that can interfere with capturing short replies.
4) Evaluate providers/models if accuracy remains poor
• Some backends handle short conversational utterances better (Deepgram/Soniox/AssemblyAI have options for keyword boosting and conversational models). If auto chooses a backend that doesn’t support keyterm biasing, switching to a specific provider that does will help.
5) Logging & testing
• Log raw audio snippets and corresponding STT outputs for short replies to see whether audio is being truncated, recognized incorrectly, or lost.
• Record examples where “no” fails and test with keyterms and lowered VAD thresholds to measure improvement.
If you want, I can:
• Suggest the exact turnHandling and STT modelOptions snippet for your current code.
• Propose specific values for min_interruption_duration and falseInterruptionTimeout based on whether your app favors speed or robustness.
Which would you like me to provide?
Sources: AssemblyAI STT | LiveKit Documentation | Deepgram STT | LiveKit Documentation | Soniox STT plugin guide | LiveKit Documentation | ElevenLabs STT | LiveKit Documentation | Amazon Transcribe plugin guide | LiveKit Documentation, with interactive elements