Feb 17 05:35:01 ip-172-31-23-35.ec2.internal pytho...
# ask-ai
w
Feb 17 053501 ip-172-31-23-35.ec2.internal python3[1599332]: {"message": "Task exception was never retrieved\nfuture: <Task finished name='agent_job_termination' coro=<AgentServer._handle_termination() done, defined at /home/ec2-user/livekit-agent/venv/lib64/python3.11/site-packages/livekit/agents/worker.py:1257> exception=ValueError('process object is closed')>", "level": "ERROR", "name": "asyncio", "exc_info": "Traceback (most recent call last):\n File \"/usr/lib64/python3.11/asyncio/tasks.py\", line 500, in wait_for\n return fut.result()\n ^^^^^^^^^^^^\nasyncio.exceptions.CancelledError\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/home/ec2-user/livekit-agent/venv/lib64/python3.11/site-packages/livekit/agents/ipc/supervised_proc.py\", line 252, in aclose\n await asyncio.wait_for(\n File \"/usr/lib64/python3.11/asyncio/tasks.py\", line 502, in wait_for\n raise exceptions.TimeoutError() from exc\nTimeoutError\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/home/ec2-user/livekit-agent/venv/lib64/python3.11/site-packages/livekit/agents/worker.py\", line 1262, in _handle_termination\n await proc.aclose()\n File \"/home/ec2-user/livekit-agent/venv/lib64/python3.11/site-packages/livekit/agents/ipc/supervised_proc.py\", line 261, in aclose\n await self._send_kill_signal()\n File \"/home/ec2-user/livekit-agent/venv/lib64/python3.11/site-packages/livekit/agents/ipc/supervised_proc.py\", line 317, in _send_kill_signal\n self._proc.kill()\n File \"/usr/lib64/python3.11/multiprocessing/process.py\", line 139, in kill\n self._check_closed()\n File \"/usr/lib64/python3.11/multiprocessing/process.py\", line 101, in _check_closed\n raise ValueError(\"process object is closed\")\nValueError: process object is closed", "timestamp": "2026-02-17T053501.739057+00:00"}
t
Thanks for reaching out, Sujata. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — that log is helpful. I’m responding to the ValueError: "process object is closed" that occurred while the agent was attempting to terminate a job process. Summary of what happened • The agent tried to close a supervised subprocess during shutdown/termination. • While awaiting
proc.aclose()
a timeout/cancellation occurred, then the code attempted
self._proc.kill()
. • Python raised ValueError("process object is closed") because the multiprocessing Process had already been closed (exited or otherwise cleaned up) before the kill was attempted. What this means for you • This is a process lifecycle race: the agent attempted to force-kill a process that had already been closed, which produces noisy error logs but does not necessarily indicate the job failed in a way that affects other jobs. • You may still want to eliminate the exception to reduce log noise and ensure clean shutdown behavior. Recommended next steps (actionable) 1. Add a safe-check before calling kill ◦ Update the kill/send-kill logic to skip calling
kill()
when the process is already closed or not alive. Example:
Copy code
if self._proc is None or not self._proc.is_alive():
       return
   self._proc.kill()
• This prevents ValueError when the process has already terminated. 1. Catch and ignore ValueError at shutdown ◦ Wrap the termination sequence in a try/except so a closed-process error is handled gracefully:
Copy code
try:
       await self._send_kill_signal()
   except ValueError:
       # process already closed, nothing to do
       pass
1. Make
aclose()
tolerant to already-closed processes ◦ When implementing
aclose()
, check process state and avoid sending signals if closed; also catch
asyncio.TimeoutError
and
ValueError
and proceed to cleanup. 1. Add debug logging around termination ◦ Log process state immediately before attempting termination so you can confirm whether the process was already dead:
Copy code
logger.debug(f"Terminating job {job_id}; process alive={self._proc.is_alive()}")
1. Check shutdown sequencing and external signals ◦ Verify no external lifecycle (container/platform) signal causes the process to exit prior to agent termination logic. ◦ Confirm
drain_timeout
and graceful-shutdown settings are appropriate for your jobs so forced-kill logic is rarely needed. If you want, I can: • Point to the specific files and lines to change if you share the agent version or repo layout. • Draft a small patch for
SupervisedProc.aclose()
and the
_handle_termination
handler that implements the checks and exception handling above. • Help interpret further logs if this error recurs after changes (please include the agent version and the surrounding logs). Which would you like to do next? Sources: Job lifecycle | LiveKit Documentation | Server options | LiveKit Documentation | Self-hosted deployments | LiveKit Documentation