{"record":{"id":"5428925a9e3e6f31","repo":"stablyai/orca","slug":"terminal-session-owner-could-not-be-verified-se","errorCode":null,"errorMessage":"Terminal session owner could not be verified: ${sessionId}","messagePattern":"Terminal session owner could not be verified: (.+?)","errorType":"exception","errorClass":"TerminalSessionOwnerUnverifiedError","httpStatus":null,"severity":"error","filePath":"src/main/daemon/daemon-session-owner-resolution.ts","lineNumber":99,"sourceCode":"        }\n        if (this.providers.length === 1) {\n          throw error\n        }\n        if (routed && this.routes.get(opts.sessionId) === routed) {\n          this.forgetRoute(opts.sessionId, routed)\n        }\n      }\n    }\n\n    assertClientConnected(opts.signal)\n    const resolution = await this.resolve(\n      opts.sessionId,\n      opts.expectedIncarnationId,\n      opts.expectedIncarnationIsAuthoritative\n    )\n    assertClientConnected(opts.signal)\n    if (resolution.kind === 'unknown') {\n      throw new TerminalSessionOwnerUnverifiedError(opts.sessionId)\n    }\n    if (resolution.kind === 'absent') {\n      throw new SessionNotFoundError(opts.sessionId)\n    }\n    try {\n      const result = await resolution.provider.spawn(opts)\n      if (\n        !result.exitedBeforeSpawnReply &&\n        result.id === opts.sessionId &&\n        result.isReattach === true\n      ) {\n        this.recordRoute(result.id, resolution.provider, result.incarnationId)\n      }\n      return result\n    } catch (error) {\n      if (error instanceof SessionNotFoundError && this.providers.length > 1) {\n        throw new TerminalSessionOwnerUnverifiedError(opts.sessionId)\n      }","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/daemon/daemon-session-owner-resolution.ts#L81-L117","documentation":"TerminalSessionOwnerUnverifiedError: during attach-only spawn, resolve() returned kind 'unknown', meaning the daemon could not determine which provider owns the session. This is distinct from 'absent' (the session provably does not exist) — 'unknown' means the inventory was incomplete or the epoch changed mid-resolution (a provider was invalidated concurrently), so ownership is un-verifiable rather than definitely missing.","triggerScenarios":"spawnAttachOnly where the provider inventory was incomplete (a provider failed to report) or the epoch changed during resolution because invalidateProvider() ran (e.g., a daemon adapter disconnected between inventory and resolution), leaving no authoritative answer.","commonSituations":"Multiple PTY providers registered and one becomes unreachable during attach; a daemon handover invalidating routes mid-call; concurrent session teardown racing an attach on a multi-provider host (WSL + native, or daemon + fallback).","solutions":["Retry spawnAttachOnly after a short backoff — the epoch change or provider cooldown (1s) is transient and a fresh inventory may resolve cleanly.","Ensure all expected providers are healthy before issuing attach; if a provider is permanently gone, remove it so inventory can complete.","If retries keep returning unknown, fall back to creating a fresh session rather than looping on an un-resolvable attach.","Check that invalidateProvider is not being called spuriously during steady-state attaches."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"import { TerminalSessionOwnerUnverifiedError } from './daemon-errors'\nfunction isOwnerUnverified(e: unknown): boolean {\n  return e instanceof TerminalSessionOwnerUnverifiedError\n}","tryCatchPattern":"for (let attempt = 0; attempt < 3; attempt++) {\n  try {\n    return await resolver.spawnAttachOnly(opts)\n  } catch (e) {\n    if (e instanceof TerminalSessionOwnerUnverifiedError && attempt < 2) {\n      await delay(100 * (attempt + 1))  // let epoch/cooldown settle\n      continue\n    }\n    throw e\n  }\n}","preventionTips":["Avoid spurious invalidateProvider calls during steady-state attaches.","Keep provider health stable so inventory completes authoritatively.","Cap retries and fall back to creating a fresh session if ownership stays unknown."],"tags":["session","ownership","resolution","attach"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}