{"record":{"id":"892298d906df62e6","repo":"stablyai/orca","slug":"session-not-found-sessionid-892298","errorCode":null,"errorMessage":"Session not found: ${sessionId}","messagePattern":"Session not found: (.+?)","errorType":"exception","errorClass":"SessionNotFoundError","httpStatus":null,"severity":"error","filePath":"src/main/daemon/terminal-host.ts","lineNumber":245,"sourceCode":"    this.disposePromise = disposePromise\n    void disposePromise.catch(() => {\n      // Why: keep failed native owners retryable on a later shutdown request.\n      if (this.disposePromise === disposePromise) {\n        this.disposePromise = null\n      }\n    })\n    return disposePromise\n  }\n\n  private async disposeSessions(): Promise<void> {\n    await shutdownTerminalHostSessions(this.sessions, this.onFinalCheckpoint)\n    this.killedTombstones.clear()\n  }\n\n  private getAliveSession(sessionId: string): Session {\n    const session = this.sessions.get(sessionId)\n    if (!session || !session.isAlive) {\n      throw new SessionNotFoundError(sessionId)\n    }\n    return session\n  }\n}\n","sourceCodeStart":227,"sourceCodeEnd":250,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/daemon/terminal-host.ts#L227-L250","documentation":"SessionNotFoundError is thrown by TerminalHost.getAliveSession when a sessionId resolves to no entry in the sessions Map, or to a session whose isAlive flag is false. It guards every command-targeting method (write, resize, signal, clearScrollback, closeStartupQueryAuthority, inspectProcess, getCwd) so operations cannot be applied to a dead or nonexistent PTY. The class carries a stable name ('SessionNotFoundError') so callers across the daemon protocol boundary can branch on it.","triggerScenarios":"Calling host.write(sessionId, data), host.resize, host.signal, host.clearScrollback, host.closeStartupQueryAuthority, host.inspectProcess, or host.getCwd with a sessionId that has already exited (onSessionExit ran and reapSession deleted it) or was never created. Also reachable when a client sends input to a pane whose shell has terminated but the renderer has not yet been notified.","commonSituations":"A terminal pane whose shell exited but the client still sends keystrokes; a stale sessionId persisted across a daemon restart (the session map is in-memory); a race where the user closes a tab mid-operation and a queued resize/write arrives after reapSession; referencing a sessionId from a different daemon incarnation.","solutions":["Catch SessionNotFoundError by name at the client/RPC handler boundary and treat it as a benign session-gone condition (close the pane, stop sending input) rather than surfacing a crash.","Before issuing commands, check host.listSessions() or a cached liveness flag if you suspect the session may have exited.","Ensure the UI tears down pane state on receipt of the session-exit event so no further write/resize calls are dispatched.","If you hold a sessionId long-term, subscribe to its exit notification and null your reference on exit."],"exampleFix":"// before: unguarded write crashes on exited session\nhost.write(sessionId, keystroke)\n// after: tolerate a session that exited between events\ntry {\n  host.write(sessionId, keystroke)\n} catch (e) {\n  if (e instanceof SessionNotFoundError) {\n    onSessionGone(sessionId)\n    return\n  }\n  throw e\n}","handlingStrategy":"try-catch","validationCode":"// Cheap pre-check before issuing a command to a possibly-dead session.\nimport type { SessionInfo } from './types'\nfunction sessionLikelyLive(host: TerminalHost, sessionId: string): boolean {\n  return host.listSessions().some((s: SessionInfo) => s.id === sessionId)\n}","typeGuard":"import { SessionNotFoundError } from './types'\nfunction isSessionNotFound(e: unknown): e is SessionNotFoundError {\n  return e instanceof SessionNotFoundError\n}","tryCatchPattern":"try {\n  host.write(sessionId, data)\n} catch (e) {\n  if (e instanceof SessionNotFoundError) {\n    onSessionGone(sessionId) // close pane, stop sending\n    return\n  }\n  throw e\n}","preventionTips":["Null out sessionId references on receipt of the session-exit event.","Treat SessionNotFoundError as expected at every RPC handler boundary, not as a crash.","Do not persist sessionIds across daemon restarts; the map is in-memory."],"tags":["session-lifecycle","terminal-host","null-state","daemon"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}