Repository navigation
Description
Symptom
After an app restart every OpenCode Terminal pane comes back blank and, about 32 s later, flips to failed ("Timed out waiting for agent to become ready for input"); the process is gone. Waking the same pane manually afterwards works in 2–4 s. Owner's report: "opencode terminal resume is fucked up".
Evidence
Incidents journal ~/.config/agent-code/incidents/runs/2026-09-03T23-43-59-…/events.jsonl (app restart after app.prior_unclean_shutdown):
- 23:44:02.6
recover.request×3 (calleragent-terminal-leaf.attach-retry,hasResumeId: true). - 23:44:04.9
recover.spawned … lifecycle: "live", ready: false(providerStart 2–3 ms;psshowsopencode --session ses_… --auto, the correct CLI form on 1.18.27). - 23:44:34.9
kill.request cause: "live-entry"+wake.result ok:false code:"start-failed" durationMs: 32283/32415/32447for all three; noexitin between — the processes were alive. ~/.local/share/opencode/log/opencode.loghas no run between 23:06 and 23:45:33: the three TUIs never reached their first log line inside 30 s (ten Claude sessions were rehydrating concurrently;opencode.dbis 1.47 GB and every invocation opens it).- Same session re-woken manually at 23:45:33 →
ready: truein 1.7 s.
Mechanism
src/renderer/src/workspace/hook/actions/session.ts ensureSessionLive (~699-736): after session:recover returns disposition: 'spawned', ready: false, it runs waitForSessionInputReady with a hard-coded 30 s (~198-201, 703) and on timeout calls killSessionBackendIfOwned and marks the pane failed/start-failed (~734-773). For the terminal runtime "input ready" is merely first PTY byte + 250 ms (src/providers/opencode/runtime/opencodeTerminalSession.ts:130-146) — a boot-latency measurement, not a health signal — and on this machine TUI boot ranges from 0.5 s idle to >30 s during restart. AgentTerminalLeaf.tsx (~366-372) only retries its attach after the wake resolves, so the pane is also blank for the whole boot even when it succeeds.
Identity capture and the CLI resume form are correct (opencodeCliSessions.ts:97-118, opencodeTerminalSession.ts:112-123; workspace.json holds providerSessionId: "ses_…").
Expected
- A readiness timeout must never kill a backend that has not exited: leave the pane
startedand not-ready (the existing "accepted cost" comment already argues this); keep the kill only forexited/failed. ForproviderRuntime === 'terminal'skip the readiness wait, like theadoptedLiveBackendshort-circuit. AgentTerminalLeafretries the attach as soon as the recover RPC resolves (backend live), not after readiness, so the booting TUI is visible immediately.
Tests
sessionRecovery.renderer.test.tsx: spawned terminal-runtime backend that never publishes ready → wake resolves ok, no kill, panestarted; spawned non-terminal backend past the deadline but not exited → not killed.- Leaf test: first attach null, recover resolves before readiness → attach retried and buffer replayed before ready.
- Deterministic repro: point
setup.json.toolPaths.opencodeat a wrapper that sleeps 35 s then execs opencode; restart with one OpenCode Terminal pane.
Related: deliverPromptText has a 15 s readiness cap (opencodeTerminalSession.ts:14, 206-227) that fails under the same load; rehydrate.ts:64 shares the fragile 30 s constant. Also a factor in the ~3-minute boot the owner reports.
Activity
docs(sessions): record wake-readiness verification
test(sessions): expect the joiner disposition in concurrent recovery
chore(sessions): integrate wake recovery with current terminal throug…
Juliusolsson05 commentedon Sep 5, 2026
Wake-readiness repair #776 is validated on final head 87ca7e9: both full host CI gates pass. A readiness deadline no longer kills a live backend; raw terminal attachment skips composer readiness. This does not resolve the separate boot-concurrency/I/O backlog. Awaiting owner merge confirmation; live agents were not restarted.
fix(incidents): tag Codex handoff and shutdown-time kills by their re…