stablyai/orca · error · SessionNotFoundError
Session not found: ${sessionId}
Error message
Session not found: ${sessionId} What it means
SessionNotFoundError from createOrAttachTerminalSession: the session id is in active teardown (sessionTeardown holds it) or the existing session is marked isTerminating. Descendant capture must finish before attach or recreation, so a session being torn down is reported as not found rather than handed out — handing it out could deliver a doomed session to the caller while teardown owns its process.
Source
Thrown at src/main/daemon/terminal-host-session-create.ts:39
onDeadSessionRemoved: (sessionId: string) => void
onSessionCreated: (sessionId: string, generation: string | undefined, isAlive: boolean) => void
onSessionExit: (sessionId: string, generation: string | undefined) => void
}
export async function createOrAttachTerminalSession(
opts: InternalCreateOrAttachOptions,
deps: TerminalHostSessionCreateDependencies
): Promise<CreateOrAttachResult> {
if (deps.creationFenced) {
throw new Error('Terminal host is shutting down')
}
opts.onSessionResolved?.(opts.sessionId)
const existing = deps.sessions.get(opts.sessionId)
// Why: descendant capture must finish before attach or recreation, or the
// caller could receive a doomed session while teardown owns its process.
if (deps.sessionTeardown.get(opts.sessionId) || existing?.isTerminating) {
throw new SessionNotFoundError(opts.sessionId)
}
if (existing && existing.isAlive && !existing.isTerminating) {
const snapshot = existing.getSnapshot()
existing.detachAllClients()
const token = existing.attachClient(opts.streamClient)
return {
isNew: false,
snapshot,
pid: existing.pid,
shellState: existing.shellState,
incarnationId: existing.incarnationId,
...getDaemonSessionResultMetadata(existing),
attachToken: token
}
}
if (existing?.isAlive && existing.isTerminating) {View on GitHub (pinned to 1136503c6a)
Solutions
- Wait for the session's teardown to complete (descendant capture) before retrying createOrAttach.
- If attaching, retry after the terminating session is fully reaped.
- Avoid issuing createOrAttach for ids known to be in teardown; track teardown state client-side.
- If recreation is intended, ensure prior teardown finishes first so a new generation can spawn cleanly.
Defensive patterns
Strategy: retry
Validate before calling
// Check teardown state before createOrAttach to avoid the not-found round-trip
if (deps.sessionTeardown.get(sessionId) || existing?.isTerminating) {
await waitForTeardown(sessionId)
} Type guard
import { SessionNotFoundError } from './types'
function isSessionNotFoundDuringTeardown(e: unknown): boolean {
return e instanceof SessionNotFoundError
} Try / catch
try {
return await createOrAttachTerminalSession(opts, deps)
} catch (e) {
if (e instanceof SessionNotFoundError && isSessionInTeardown(sessionId)) {
await waitForTeardownComplete(sessionId)
return await createOrAttachTerminalSession(opts, deps)
}
throw e
} Prevention
- Wait for a session's teardown (descendant capture) to finish before reusing its id.
- Track teardown state client-side to avoid issuing createOrAttach for ids being torn down.
- Serialize kill->teardown->recreate rather than overlapping them.
When it happens
Trigger: createOrAttachTerminalSession where deps.sessionTeardown.get(opts.sessionId) is truthy or existing?.isTerminating is true, hit before the live-attach or terminate-specific branches.
Common situations: A createOrAttach for a sessionId that is concurrently being killed/teardown; an attach racing session exit; recreating a session whose teardown has not finished capturing descendants.
Related errors
- browser_debugger_detached
- Session not found: ${sessionId}
- Session "${opts.sessionId}" is terminating
- Wayland GPU sandbox validation requires a Wayland session.
- Refusing to use an unexpected guest cleanup path
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/ff2f13e67c37b3f1.
Report an issue: GitHub.