Bug
After the Codex App Server is terminated by SIGKILL, sending another message to the same T3 thread repeatedly fails with ProviderAdapterSessionClosedError: codex adapter thread is closed. Retrying the message does not recreate the Codex process. The T3 server itself remains healthy.
Observed on Linux with T3 Code v0.1.69. In the incident, the process exited hours before the next user message; both the first message and its retry failed against the same closed adapter thread.
Reproduction
- Start a Codex-backed T3 thread and let its App Server session become active.
- Terminate that App Server process with
SIGKILL (for example, through a memory pressure manager).
- Send a new message to the same thread, then retry it.
Expected: T3 marks the old session as exited and resumes the native Codex thread in a fresh App Server process before sending the new turn. The interrupted turn itself need not be replayed.
Actual: The adapter keeps routing turns to the closed process; each send fails with ProviderAdapterSessionClosedError.
Diagnosis and related work
Two lifecycle gaps combine in this case:
- Signal termination makes
child.exitCode fail, while the runtime watcher only handles a successful numeric exit status. Consequently it can miss session/exited for SIGKILL.
- Even when an exit event is emitted, the Codex adapter can retain the dead runtime in its session map, so
hasSession remains true and recovery is skipped.
Related: #10798 describes the retained session and indefinitely running UI state. #10799 addresses adapter cleanup; #10874 addresses signal exits. This issue tracks the user-visible repeated-turn failure when both gaps occur together and the need for an integration regression covering the full path.
Bug
After the Codex App Server is terminated by
SIGKILL, sending another message to the same T3 thread repeatedly fails withProviderAdapterSessionClosedError: codex adapter thread is closed. Retrying the message does not recreate the Codex process. The T3 server itself remains healthy.Observed on Linux with T3 Code v0.1.69. In the incident, the process exited hours before the next user message; both the first message and its retry failed against the same closed adapter thread.
Reproduction
SIGKILL(for example, through a memory pressure manager).Expected: T3 marks the old session as exited and resumes the native Codex thread in a fresh App Server process before sending the new turn. The interrupted turn itself need not be replayed.
Actual: The adapter keeps routing turns to the closed process; each send fails with
ProviderAdapterSessionClosedError.Diagnosis and related work
Two lifecycle gaps combine in this case:
child.exitCodefail, while the runtime watcher only handles a successful numeric exit status. Consequently it can misssession/exitedforSIGKILL.hasSessionremains true and recovery is skipped.Related: #10798 describes the retained session and indefinitely running UI state. #10799 addresses adapter cleanup; #10874 addresses signal exits. This issue tracks the user-visible repeated-turn failure when both gaps occur together and the need for an integration regression covering the full path.