You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(session): wake readiness timeout kills a live codex blocked on its trust dialog — 30s kill loop #712
Waking/retrying a Codex pane whose screen shows a resolvable condition (the trust dialog) keeps the process alive and waits for the user: a visible condition is proof the backend is alive and painting.
Actual behavior
The wake's 30-second readiness timeout kills the live Codex process while the trust dialog legitimately blocks readiness, producing a kill/respawn loop: every respawn repaints the trust dialog, readiness never latches, and 30s later the backend is killed again.
Evidence
App run 2026-08-31T00-48-19-592Z-main-63968-59a3af, codex session 9d9fd575… (project bringdown):
01:17:07.761 provider.start.begin kind=codex
01:17:35.258 recover.request caller=tile-leaf.retry
01:17:35.757 recover.spawned disposition=spawned ready=false reason=provider-not-ready
01:18:05.812 kill.request cause=live-entry ← exactly 30s after the wake
Codex readiness latches only at markComposerReady, and the trust dialog paints before the composer ever appears — so readiness cannot arrive while the dialog is up. This is the documented #596/#597 failure class ("armed a 30-second timer that KILLED the live backend"), reachable again through ensureSessionLive's wake-spawned path (hook/actions/session.ts readiness wait): #597 exempted adopted live backends, but a wake that spawns (recover of a dead pane in an untrusted folder) still arms the kill timer against a backend that is alive and waiting on the user.
Impact
Any wake of a Codex pane in a not-yet-trusted folder murders the backend on a 30s cycle. Combined with #711 (clicks never resolving the dialog), the pane is permanently unusable. This also burns the trust dialog's own lifetime — the user gets ~30s windows to act.
Fix direction
The readiness wait must treat "a visible, resolvable condition is on screen" as alive-and-waiting-on-user, not as failed boot: suspend or cancel the kill timer while the session's condition snapshot holds a resolvable condition (trust dialog, approval), and resume the readiness budget when it clears. Alternatively, wake-spawned sessions should follow the same rule #597 gave adopted ones whenever a condition is visible.
Fixed on main and never closed. b83ff9cc ("stop killing slow-booting backends on the readiness timeout", Fixes #772).
The readiness-wait catch now inspects the observed runtime (hook/actions/session.ts ~:905-960): if the backend has not failed and has not exited, it sets readyTimedOut, resolves the wake and journals wake.result ok:true code:'ready-timeout'. The kill is reachable only via readyError && recoveryDisposition === 'spawned', and readyError is set only on an observed exit or start failure. A Codex sitting on an unanswered trust dialog is alive and not failed, so the 30s deadline cannot kill it and the kill/respawn loop in this issue cannot occur.
Tests: sessionRecovery.renderer.test.tsx:341 advances 31s and asserts killOwnedSession was not called and the runtime stays started/exited:null; :359 proves it still fails when the backend really does exit.
Fixed by a broader rule than the condition-aware suspension this issue proposed — "alive and not failed" needs no knowledge of trust dialogs — and independently ed9e852f now pre-trusts the spawn folder so app-spawned Codex sessions never paint that dialog at all.
Activity
Juliusolsson05 commentedon Sep 20, 2026
Fixed on main and never closed.
b83ff9cc("stop killing slow-booting backends on the readiness timeout",Fixes #772).The readiness-wait catch now inspects the observed runtime (
hook/actions/session.ts~:905-960): if the backend has not failed and has not exited, it setsreadyTimedOut, resolves the wake and journalswake.result ok:true code:'ready-timeout'. The kill is reachable only viareadyError && recoveryDisposition === 'spawned', andreadyErroris set only on an observed exit or start failure. A Codex sitting on an unanswered trust dialog is alive and not failed, so the 30s deadline cannot kill it and the kill/respawn loop in this issue cannot occur.Tests:
sessionRecovery.renderer.test.tsx:341advances 31s and assertskillOwnedSessionwas not called and the runtime staysstarted/exited:null;:359proves it still fails when the backend really does exit.Fixed by a broader rule than the condition-aware suspension this issue proposed — "alive and not failed" needs no knowledge of trust dialogs — and independently
ed9e852fnow pre-trusts the spawn folder so app-spawned Codex sessions never paint that dialog at all.