Hey, following up on the connection leak investiga...
# ask-ai
m
Hey, following up on the connection leak investigation — we found another shutdown issue. When running the agent directly via CLI (
livekit:dev
/
npx tsx ... dev
) and hitting Ctrl+C, we get an unhandled EPIPE crash:
Copy code
Error: write EPIPE
    at target._send (node:internal/child_process:877:20)
    at target.send (node:internal/child_process:751:19)
    at <anonymous> (node_modules/@livekit/agents/dist/ipc/inference_proc_lazy_main.js:81:21)
followed by:
Copy code
libc++abi: terminating due to uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
What's happening: SIGINT hits both the CLI and inference processes simultaneously. The CLI shuts down the worker and closes the IPC pipe, but the inference process (
inference_proc_lazy_main.js:81
) still tries to
process.send()
back — pipe is gone, unhandled EPIPE, which cascades into the native RTC addon mutex crash. Running through a process manager (like turborepo's
turbo watch
) that sequences the shutdown signals avoids this since the IPC pipes are still intact when children communicate. So it's not blocking us day-to-day, but it does make local
dev
mode less clean. SDK version:
@livekit/agents
1.0.47, Node 22.14.0, macOS Seems like wrapping that
process.send
in a try-catch or adding a
process.on('error')
handler in the inference proc would fix it
t
Thanks for reaching out, Karan. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — this is very helpful and clear. I’m responding about the unhandled EPIPE crash you reported when pressing Ctrl+C in dev mode (SIGINT reaching CLI and inference proc simultaneously), and your suggestion to guard
process.send()
. What you’ve described matches the root cause: the CLI closes the IPC pipe while the inference process still calls
process.send()
, which raises an unhandled EPIPE and then cascades into the native RTC addon mutex failure. Running under a process manager that sequences shutdown avoids the race, which confirms this is a shutdown race-condition in local dev mode. What you can try locally (quick mitigations) • Add a
process.on('error', ...)
handler in the inference process to catch IPC errors and prevent uncaught exceptions. • Wrap the
process.send(...)
call in a try/catch and ignore EPIPE (or perform a safe shutdown path) so the inference process can exit cleanly. • Before calling
process.send()
, check
process.connected
(true if the IPC channel is open) and skip sending if it’s false. Why those help •
process.connected
prevents attempts to write to a closed pipe. • A guarded
process.send()
or an
error
handler prevents the unhandled exception that triggers the native addon crash, so shutdown completes cleanly even with simultaneous SIGINT. Next steps from our side • I’ll escalate this to the engineering team for a code fix in the agents package so dev-mode shutdown is resilient by default (for example, adding the
process.connected
check and an IPC error handler, or surrounding
process.send()
with try/catch). This aligns with improving developer experience in
dev
mode. If you’d like, please share: • The small snippet around the
process.send()
call (the file
inference_proc_lazy_main.js
near line 81) you’re seeing locally — that will help us propose the exact patch and speed up the fix. • Whether you prefer a temporary patch you can apply locally (I can suggest an edit) or you’d rather wait for an SDK patch from the team. Thanks again for the clear report and mitigation suggestion — this is exactly the kind of edge case we want to make robust for local development. Sources: Agent speech and audio | LiveKit Documentation | Voice AI quickstart | LiveKit Documentation | Server startup modes | LiveKit Documentation
m
@loud-dawn-97520 sorry to bother you but will this bot actually escalate to the engineering team or would you like me to email this too?
t
Thanks — great question. I will escalate this to engineering on your behalf, so no need to email them yourself unless you want to. What I’ll do: • Pass your report, the stack traces, and your suggested mitigation (guarding process.send / process.on('error') / check process.connected) to the engineering team for evaluation and a patch. • Include the note that the issue reproduces with direct CLI runs (Ctrl+C) but not when using a process manager that sequences shutdown. If you’d like me to include anything extra in that report, please share: • The exact snippet around
process.send()
in your local
inference_proc_lazy_main.js
(near line 81), or • Any additional reproduction steps, timestamps, or a minimal repo/commands that reliably reproduce the crash. Otherwise I’ll escalate now with the details you’ve already provided. Which would you prefer?