Skip to content

Ctrl+C (SIGINT) causes uvloop exception when stopping agent worker #4664

@luisa-libby

Description

@luisa-libby

Bug Description

Description:
When stopping a LiveKit agent worker with Ctrl+C, an exception is logged from uvloop even though the process exits. This happens consistently on macOS.
Environment:
• Python 3.11
• livekit-agents (latest version)
• macOS (darwin 25.2.0)
• uvloop installed

Expected Behavior

Worker stops cleanly without exceptions.

Reproduction Steps

Steps to Reproduce:
  1. Start a LiveKit agent worker with python -m app.livekit_worker start
  2. Let it run (optionally handle a call)
  3. Press Ctrl+C to stop the worker

The worker stops but logs this exception:

  {"message": "process exiting", "level": "INFO", "name": "livekit.agents", "reason": "", "pid": 74962, "job_id": "AJ_Z4XfbcaZDXsb", "room_id": "RM_vrjENkAaKrDR", "timestamp": "2026-01-30T17:51:09.244849+00:00"}
  {"message": "Exception in callback Loop._read_from_self\nhandle: <Handle Loop._read_from_self>", "level": "ERROR", "name": "asyncio", "exc_info": "Traceback (most recent call last):\n  File \"uvloop/cbhandles.pyx\",
  line 66, in uvloop.loop.Handle._run\n  File \"uvloop/loop.pyx\", line 399, in uvloop.loop.Loop._read_from_self\n  File \"uvloop/loop.pyx\", line 404, in uvloop.loop.Loop._invoke_signals\n  File \"uvloop/loop.pyx\",
  line 379, in uvloop.loop.Loop._ceval_process_signals\n  File \"/path/to/venv/lib/python3.11/site-packages/livekit/agents/cli/cli.py\", line 1304, in _handle_exit\n    raise
  _ExitCli()\nlivekit.agents.cli.cli._ExitCli", "timestamp": "2026-01-30T17:51:50.080599+00:00"}

Operating System

macos

Models Used

No response

Package Versions

Environment:
  • Python 3.11
  • livekit-agents (latest version)
  • macOS (darwin 25.2.0)
  • uvloop installed

Session/Room/Call IDs

No response

Proposed Solution

The _ExitCli exception raised in _handle_exit (cli.py:1304) propagates through uvloop's signal handling, causing it to log as an error. The exception is intentional for control flow but uvloop treats it as an
  unhandled exception in the callback.
  Workaround:
  None currently - the process does exit, the error is just cosmetic/noisy.

Additional Context

No response

Screenshots and Recordings

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions