fancy-easter-44489
02/20/2026, 1:48 AM{
"message": "error decoding audio\nTraceback (most recent call last):\n File \"/app/.venv/lib/python3.13/site-packages/livekit/agents/utils/codecs/decoder.py\", line 168, in _decode_loop\n container = av.open(\n self._input_buf,\n ...<11 lines>...\n },\n )\n File \"av/container/core.pyx\", line 482, in av.container.core.open\n File \"av/container/core.pyx\", line 298, in av.container.core.Container.__cinit__\n File \"av/container/core.pyx\", line 318, in av.container.core.Container.err_check\n File \"av/error.pyx\", line 424, in av.error.err_check\nav.error.EOFError: [Errno 541478725] End of file: '<none>'",
"level": "ERROR",
"name": "livekit.agents",
"exc_info": "Traceback (most recent call last):\n File \"/app/.venv/lib/python3.13/site-packages/livekit/agents/utils/codecs/decoder.py\", line 168, in _decode_loop\n container = av.open(\n self._input_buf,\n ...<11 lines>...\n },\n )\n File \"av/container/core.pyx\", line 482, in av.container.core.open\n File \"av/container/core.pyx\", line 298, in av.container.core.Container.__cinit__\n File \"av/container/core.pyx\", line 318, in av.container.core.Container.err_check\n File \"av/error.pyx\", line 424, in av.error.err_check\nav.error.EOFError: [Errno 541478725] End of file: '<none>'",
"room": "44dbe75c-0d19-416b-b982-9b3de1433512",
"pid": 13098,
"job_id": "AJ_2rLj358sunZM",
"room_id": "RM_xrNinqecKwiq",
"timestamp": "2026-02-18T23:23:08.000607+00:00"
}tall-airline-16756
02/20/2026, 1:48 AMtall-airline-16756
02/20/2026, 1:49 AMav.error.EOFError: [Errno 541478725] End of file: '<none>' raised from the LiveKit Agents decoder when calling av.open() on the input buffer.
What this means (brief)
• The decoder attempted to open or read media from an input buffer but found no usable data — an end-of-file condition on an empty or incomplete buffer.
• Common causes: the incoming audio stream ended unexpectedly or never contained audio, the buffer was already consumed/cleared before decoding, or a disruption in the media pipeline (e.g., a track ended or a network interruption).
What you can check next
• When does the error occur?
◦ During live playback, when starting a transcription job, after a participant leaves, or at another specific point?
• Consistency
◦ Does this happen every time for the same room/job or only intermittently?
• Agent lifecycle and buffer handling
◦ Confirm the code path that writes audio into the buffer passed to the decoder and ensure the buffer contains data before calling av.open().
◦ Ensure you’re not closing or emptying the buffer earlier in the pipeline or reusing a buffer that’s already been consumed.
• Media lifecycle events
◦ Check if the track has signaled ended/stopped immediately before the decode attempt. If so, guard the decoder call with a check that the track is still active and data is available.
• Recent changes
◦ Any recent code changes around media capture, buffering, or track lifecycle handling?
• Versions & environment
◦ Which versions of livekit-agents and pyav (or av) are you running?
◦ Runtime environment (Python version, OS/container) can also help.
Suggested quick mitigations
• Add a pre-check to ensure the input buffer has data before calling av.open() and log the buffer size/length when the call fails.
• Add retry logic or a graceful fallback when EOF is encountered (for transient network interruptions).
• If the error correlates with a track ending, skip decode attempts once the track end is observed.
If you want, please share the following so I can give a more specific recommendation:
• The context where this happens (playback, transcription, recording, etc.).
• Whether it’s reproducible and the sequence of actions to reproduce.
• livekit-agents and pyav (av) versions.
• A short snippet showing how the input buffer is created/populated and where you call the decoder (sanitized if needed).
I’ll walk through the logs/snippet and suggest targeted fixes or code changes once I have that info.fancy-easter-44489
02/20/2026, 1:54 AMtall-airline-16756
02/20/2026, 1:54 AMengine: connection error: engine is closed thrown from stream_text() when attempting to publish transcription text.
What this means (short)
• The agent is trying to send text after the underlying WebRTC engine (the room/peer connection) has already been closed. Once the engine is closed, attempts to open a data stream or send headers will raise a ConnectionError.
Immediate checks I recommend
• Where in your flow this happens: Is it after a participant leaves, during agent shutdown, or after a network interruption?
• Reproducibility: Is it consistent for the same room/job or intermittent?
• Versions: Which livekit-agents and Python `av`/`pyav` versions are you using?
• Code path: A short sanitized snippet showing how/when you call stream_text() (or the surrounding lifecycle logic) will help pinpoint the issue.
Practical fixes to prevent the error 1) Check connection state before sending
• Ensure the room/engine is still connected before calling stream_text().
Example pattern:
if not (self.session and self.session._room and self.session._room.engine.is_connected):
logger.warning("Cannot publish transcription: room connection is closed")
return
await self.session._room.local_participant.stream_text(content=text, topic="lk.transcription")
2) Stop publishing when room is closing
• Subscribe to room/engine lifecycle events and cancel or skip publishing tasks when you observe disconnection/close.
3) Drain/commit pending work on shutdown
• Before closing the session/room, commit any pending transcripts and allow in-flight audio/text tasks to finish:
await self.session.commit_user_transcript()
await self.session.output.audio.drain_speech(wait_for_playout=True)
await self.session.close()
4) Add robust error handling and optional retry
• Catch ConnectionError around stream_text() and either skip or retry with backoff only if the engine is still connected.
Example retry skeleton:
for attempt in range(max_retries):
if not self.session._room.engine.is_connected:
break
try:
await self.session._room.local_participant.stream_text(content=text)
break
except ConnectionError:
await asyncio.sleep(0.5 * (attempt + 1))
Longer-term safeguards
• Consider auto_end_on_last_participant_left=False if you need the agent to keep the room alive after humans leave.
• Log connection state transitions so you can correlate when publishes are attempted vs when the engine closes.
If you want, share any of the following and I’ll provide a targeted fix:
• The exact sequence that leads to the error (e.g., participant left → agent tried to publish).
• The snippet where you create/populate the transcription writer and call stream_text().
• livekit-agents and pyav (av) versions and whether these errors appear together or separately.
I can then suggest a minimal code change or show where to add lifecycle guards to stop attempts to publish after the engine is closed.
Sources: client-sdk-js | livekit/livekit_composite | DeepWiki | Server lifecycle | LiveKit Documentationfancy-easter-44489
02/20/2026, 5:31 AMtall-airline-16756
02/20/2026, 5:32 AMsession.start(...) with room_input_options and room_output_options and the bot isn’t interrupting. I’m responding to that specific issue.
Root cause
• The parameter names are incorrect. The session.start API expects input_options and output_options. Using room_input_options and room_output_options means your intended settings are ignored and the session runs with defaults, which can prevent interruption behavior you expect.
What to change
• Update the call to use the correct parameter names:
await session.start(
agent=agent,
room=ctx.room,
input_options=RoomInputOptions(noise_cancellation=noise_cancellation.BVCTelephony()),
output_options=RoomOutputOptions(transcription_enabled=True),
)
Other checks to ensure interruptions work
• Confirm allow_interruptions=True for the AgentSession (it’s True by default).
• Verify min_interruption_duration is low enough (default is 0.5s); reduce it if brief user speech should interrupt.
• Make sure VAD/turn-detection is configured appropriately for your audio (telephony vs. wideband). If noise cancellation is very aggressive, try disabling it briefly to rule out suppressed speech.
• Subscribe to room/turn events and log voice activity so you can see when the agent thinks a user is speaking vs when it’s speaking.
If you’d like, share:
• A short snippet of your session/agent configuration (sanitized),
• Whether you’re using a pipeline or LLM-based agent,
• Any logs showing VAD/turn events,
and I’ll suggest the minimal config changes to make interruption reliable.
Sources: Choosing the right noise cancellation for your agent | LiveKit | VAD and turn detection configuration guide | LiveKit | Turns overview | LiveKit Documentation | Interrupt User | LiveKit Documentation | How to build an agent with speech-to-text input and text-only output | Live...fancy-easter-44489
02/20/2026, 5:34 AMtall-airline-16756
02/20/2026, 5:35 AMturn_detection="stt", min_interruption_words=2, preemptive_generation=True, min_endpointing_delay=0.4, etc.). I’ll respond to that specific snippet and why the bot might still not be interrupting.
Quick summary of how this config behaves
• turn_detection="stt" uses the STT endpointing results to decide turns. That means interruptions are detected based on transcribed words and endpoint signals from STT rather than a separate turn-detector model.
• min_interruption_words=2 requires at least two transcribed words from the user before the system treats input as an interruption (this is valid and only used when STT is enabled).
• min_endpointing_delay=0.4 makes the agent wait 0.4s before treating a user turn as complete — lower values make responsiveness faster.
• preemptive_generation=True helps the agent prepare replies earlier, but doesn’t itself guarantee it will drop speech when interrupted.
Why interruptions may still not occur
• Relying on STT-only turn detection can be less responsive than using a VAD/turn-detector plugin. If STT latency or segmentation delays occur, the agent may miss short interruption windows.
• min_interruption_words=2 will ignore very brief interruptions (one-word interjections). If users say short phrases, they won’t trigger an interruption.
• Aggressive noise cancellation or VAD settings may suppress user speech so it never reaches STT as two words.
• If the session or TTS call has interruptions disabled (e.g., allow_interruptions=False on the session/reply/tts call), interruption requests will be ignored.
• If your code is still using incorrect parameter names when calling session.start() (e.g., room_input_options / room_output_options), the intended options may not be applied.
Recommended checks and small changes to try 1) Confirm correct session.start parameter names
• Use input_options and output_options — otherwise your configured options get ignored.
2) Add (or ensure) a VAD/turn-detector plugin alongside STT
• VAD + STT improves responsiveness. When using STT-based endpointing, adding a VAD plugin makes interruption detection quicker and more reliable.
3) Temporarily lower min_interruption_words
• Try min_interruption_words=0 or 1 to see if short user interjections trigger interruptions.
4) Keep min_endpointing_delay conservative
• 0.4s is reasonable; if you need faster reaction, test slightly lower values, but avoid too-low values that create false positives.
5) Verify allow_interruptions is enabled
• Ensure the AgentSession, TTS/reply calls, and any per-reply options permit interruption (it’s True by default, but confirm no explicit override).
6) Test without noise cancellation briefly
• Disable noise_cancellation to rule out suppression of user speech. If interruption improves, tune or swap the noise model.
7) Log events to debug
• Log VAD activity, STT interim/final results, and agent state transitions. That will show whether user speech reached STT and whether the agent received an interruption trigger.
Minimal experiment to isolate the issue
• Start a session with:
◦ input_options including a VAD plugin
◦ turn_detection="stt"
◦ min_interruption_words=0 (for testing)
◦ min_endpointing_delay=0.4
◦ no noise cancellation
• Record logs: VAD on/off, STT partial/final transcripts, when TTS starts/stops, and any interruption events.
If you want, paste a short sanitized snippet showing:
• Your session.start(...) call (confirming you use input_options / output_options)
• How you configure VAD or STT objects
• Any explicit allow_interruptions settings
I’ll review it and suggest the minimal config tweaks to make interruptions reliable for your use case.
Sources: Turns overview | LiveKit Documentation | VAD and turn detection configuration guide | LiveKit | LiveKit turn detector plugin | LiveKit Documentation | Agents - Field Guides | LiveKit