Skip to content

Ended a turn whose task panicked, instead of hanging. - #2

Open
moedash wants to merge 1 commit into
mainfrom
moe/fix-turn-task-panic
Open

Ended a turn whose task panicked, instead of hanging.#2
moedash wants to merge 1 commit into
mainfrom
moe/fix-turn-task-panic

Conversation

@moedash

@moedash moedash commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

What changed?

A panic in a turn task no longer escapes the spawn site in codex-rs/core/src/tasks/mod.rs. The task future runs under catch_unwind, and a panic becomes a Fatal task error, so on_task_finished emits the turn's terminal event like it does for any other failure.

Why?

That spawn site owns turn lifecycle, as its own comment says: "Finish uniformly from the spawn site so all tasks share the same lifecycle." A panic was the one path that escaped it, unwinding past both on_task_finished and done.notify_waiters().

The result is worse than a crash. A client waiting on the turn waits for a terminal event that never arrives, and the process stays alive holding the thread's writer lock, so every later resume of that thread fails with already has an active writer. codex exec hangs rather than exiting, because its wait loop only ends on an event or a closed stream.

This is the general guard. It is not hypothetical: it happened, and the specific panic that triggered it is fixed separately.

How did you test it?

  • Unit Tests
  • Staging
  • End to End Tests

describe_panic has a unit test for the payload shapes it can read.

End to end: put the old panic back, resumed a thread with a dangling tool call, and watched it log turn task panicked, emit {"type":"turn.failed",...}, and exit. The same command hung indefinitely before this change.

The spawn site owns turn lifecycle, as its comment says, but a panic in the task unwound past
both the finish hook and the waiter notification. A client waiting on the turn's terminal event
then waited for one that never came, and codex stayed alive holding the thread's writer lock,
which blocked every later resume of that thread.

Verified by restoring a panic that used to happen here and resuming a thread with a dangling
tool call: the turn now reports turn.failed and the process exits.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant