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

  1. Treat 'terminal_gone' as a terminal-not-found signal — refresh the session list and stop addressing that id.
  2. Guard inspectProcess callers with a check against getActiveSessionIds() / listSessions() first if the cost of a throw matters.
  3. 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

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


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/c7f9405a219cdd08. Report an issue: GitHub.