stablyai/orca · error · SessionNotFoundError

Session not found

Error message

Session not found: ${sessionId}

What it means

SessionNotFoundError from attachDaemonOwnedSession: an attach-only adoption was attempted against the in-process fallback PTY provider (owner === fallback). By definition a fallback pty cannot own a daemon-surviving session, and its no-op attach would falsely report success while the stream stays blank. The attach is refused so the caller seeks the real daemon owner.

Solutions

  1. Reconnect to the real daemon adapter and re-resolve the session owner before attaching.
  2. Do not mark daemon-owned session ids as owned by the fallback provider; keep the routing map accurate.
  3. If the daemon is permanently gone, create a fresh session rather than attach-adopting a fallback id.
  4. Validate that the resolved owner is not the fallback before calling attachDaemonOwnedSession.
Defensive patterns

Strategy: retry

Validate before calling

// Ensure the owner is a real daemon adapter, not the fallback, before attach-only
if (owner === fallback) {
  // reconnect to the daemon and re-resolve instead of attaching
  await reconnectDaemonAdapter()
}

Type guard

function isFallbackOwner(owner: IPtyProvider, fallback: IPtyProvider): boolean {
  return owner === fallback
}

Try / catch

try {
  return await attachDaemonOwnedSession(owner, fallback, sessionId)
} catch (e) {
  if (e instanceof SessionNotFoundError && owner === fallback) {
    const real = await resolveDaemonOwner(sessionId)
    return await attachDaemonOwnedSession(real, fallback, sessionId)
  }
  throw e
}

Prevention

When it happens

Trigger: attachDaemonOwnedSession(owner, fallback, sessionId) called where the session's route maps to the fallback provider (e.g., the daemon adapter is down and the session was degraded to the fallback), with attachOnly semantics.

Common situations: The daemon host is unavailable so sessions fell back to an in-process pty; an attach-only request arrives for one of those fallback sessions; a routing map pointing a daemon-surviving session id at the fallback provider.

Related errors


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

Appendix: source

Thrown at src/main/daemon/degraded-daemon-session-routing.ts:24

  sessionProviders: ReadonlyMap<string, IPtyProvider>,
  provider: IPtyProvider
): string[] {
  return [...sessionProviders]
    .filter(([, mappedProvider]) => mappedProvider === provider)
    .map(([id]) => id)
}

/** Attach-only session adoption: refuses the in-process fallback route. A
 *  fallback pty cannot own a daemon-surviving session by definition, and its
 *  no-op attach resolving would pin a subscriber-driven attach as succeeded
 *  while the stream stays blank. */
export async function attachDaemonOwnedSession(
  owner: IPtyProvider,
  fallback: IPtyProvider,
  sessionId: string
): ReturnType<IPtyProvider['attach']> {
  if (owner === fallback) {
    throw new SessionNotFoundError(sessionId)
  }
  return await owner.attach(sessionId)
}

/** Probes providers for an id absent from the routing map and adopts the
 *  first proven owner into the map. */
export function adoptOwningProvider(
  sessionProviders: Map<string, IPtyProvider>,
  providers: readonly IPtyProvider[],
  sessionId: string
): IPtyProvider | null {
  for (const provider of providers) {
    if (provider.hasPty?.(sessionId) === true) {
      sessionProviders.set(sessionId, provider)
      return provider
    }
  }
  return null

View on GitHub (pinned to 1136503c6a)