stablyai/orca · error
Terminal host is shutting down
Error message
Terminal host is shutting down
What it means
createOrAttachTerminalSession refuses a new session when deps.creationFenced is true. The terminal host sets the fence during shutdown/teardown so no new sessions can be spawned while it is draining. This prevents a session from being created that would immediately need to be torn down, and keeps the shutdown path deterministic.
Source
Thrown at src/main/daemon/terminal-host-session-create.ts:31
import { resolveWslSessionContext } from './wsl-session-context'
type TerminalHostSessionCreateDependencies = {
sessions: Map<string, Session>
sessionTeardown: TerminalSessionTeardown
killedTombstones: TerminalHostTombstones
spawnSubprocess: TerminalHostOptions['spawnSubprocess']
creationFenced: boolean
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,View on GitHub (pinned to 1136503c6a)
Solutions
- Do not issue create requests to a host that is shutting down; check host liveness before creating.
- On the client, treat this as a transient/reconnect condition: wait for a fresh host or reconnect to a new daemon, then retry.
- Ensure shutdown drains in-flight creates before fencing if orderly completion matters.
- Cancel pending create requests when shutdown is initiated rather than letting them hit the fence.
Defensive patterns
Strategy: retry
Type guard
function isHostShuttingDown(e: unknown): boolean {
return e instanceof Error && e.message === 'Terminal host is shutting down'
} Try / catch
try {
return await createOrAttachTerminalSession(opts, deps)
} catch (e) {
if (e instanceof Error && e.message === 'Terminal host is shutting down') {
// reconnect to a fresh host/daemon, then retry
await reconnectHost()
return await createOrAttachTerminalSession(opts, freshDeps)
}
throw e
} Prevention
- Check host liveness before issuing create requests.
- Cancel pending creates when shutdown is initiated.
- Treat this as a reconnect condition rather than a fatal error.
When it happens
Trigger: createOrAttachTerminalSession called after the host began shutting down and set creationFenced = true. Any create (non-attach) during host disposal hits this.
Common situations: A createOrAttach racing the app quit / daemon shutdown; the host fencing during an error-driven teardown while a queued create is still in flight; retries of createOrAttach after shutdown has begun.
Related errors
- relay pairing client closed
- mobile pairing cancelled
- no_active_sender_terminal
- ${result.result.lifecycle.code}
- browser_tab_not_found
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/77546d353efb27b8.
Report an issue: GitHub.