stablyai/orca · info · Error
terminal_gone
Error message
terminal_gone
What it means
DaemonPtyRouter.adapterForInspection is used by inspectProcess. It looks up the cached sessionAdapters entry, falls back to scanning allAdapters for one whose hasPty(sessionId) is true, and throws a plain Error('terminal_gone') when no adapter currently hosts that session. The router then caches the adapter on success so subsequent inspections are O(1).
Source
Thrown at src/main/daemon/daemon-pty-router.ts:321
getLegacyAdapters(): readonly DaemonPtyAdapter[] {
return this.legacy
}
getAllAdapters(): readonly DaemonPtyAdapter[] {
return this.allAdapters()
}
private adapterFor(sessionId: string): DaemonPtyAdapter {
return this.sessionAdapters.get(sessionId) ?? this.current
}
private adapterForInspection(sessionId: string): DaemonPtyAdapter {
const adapter =
this.sessionAdapters.get(sessionId) ??
this.allAdapters().find((candidate) => candidate.hasPty(sessionId))
if (!adapter) {
throw new Error('terminal_gone')
}
this.sessionAdapters.set(sessionId, adapter)
return adapter
}
private allAdapters(): DaemonPtyAdapter[] {
return [this.current, ...this.legacy]
}
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Treat 'terminal_gone' as a terminal-not-found signal — refresh the session list and stop addressing that id.
- Guard inspectProcess callers with a check against getActiveSessionIds() / listSessions() first if the cost of a throw matters.
- Avoid issuing inspection concurrently with session teardown.
Example fix
// before
const info = await router.inspectProcess(maybeStaleId)
// after
if (!router.getAllAdapters().some((a) => a.hasPty(maybeStaleId))) {
// session gone — refresh UI list
} else {
const info = await router.inspectProcess(maybeStaleId)
} Defensive patterns
Strategy: validation
Validate before calling
// before inspectProcess, confirm an adapter hosts the session
const hosted = router.getAllAdapters().some((a) => a.hasPty(sessionId))
if (!hosted) {
// session gone — refresh UI list, do not call inspectProcess
} Type guard
function isTerminalGone(e: unknown): boolean {
return e instanceof Error && e.message === 'terminal_gone'
} Try / catch
try {
const info = await router.inspectProcess(sessionId)
} catch (e) {
if (isTerminalGone(e)) {
// refresh session list; the id is no longer live
} else throw e
} Prevention
- Refresh the session list from listSessions() after any terminal-exit event before re-inspecting.
- Do not cache session ids across daemon reconnects without re-validating.
- Avoid issuing inspectProcess concurrently with session teardown.
When it happens
Trigger: Calling inspectProcess for a sessionId that was never created, has already exited and been cleaned up, or whose adapter was retired (legacy adapter dropped) before inspection.
Common situations: Renderer asking about a stale session id after the daemon restarted; concurrent teardown racing an inspection; a session that died and was reaped from all live adapters; UI list caching an old id.
Related errors
- Attach canceled for session ${sessionId}
- Daemon PTY "${id}" is awaiting recovery
- agent_session_ownership_unknown
- Session not found: ${sessionId}
- terminal_pane_owner_unverified
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/c7f9405a219cdd08.
Report an issue: GitHub.