From 70dc4e28fd4930fb26197b9fd0cc62fbf8fafba0 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Sat, 29 Aug 2026 04:10:00 -0700 Subject: [PATCH] fix(cli): preserve truthful runtime failure diagnostics --- src/cli/runtime-client.test.ts | 18 +++++++++++++++++- src/cli/runtime/client.ts | 2 +- .../local-runtime-unreachable-reason.test.ts | 7 +++++++ .../local-runtime-unreachable-reason.ts | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/cli/runtime-client.test.ts b/src/cli/runtime-client.test.ts index 71c46ad4dfe..d3d6917b54d 100644 --- a/src/cli/runtime-client.test.ts +++ b/src/cli/runtime-client.test.ts @@ -1,4 +1,4 @@ -import { mkdtempSync, writeFileSync } from 'node:fs' +import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { createServer, type Socket } from 'node:net' @@ -332,6 +332,22 @@ describe.skipIf(process.platform === 'win32')('RuntimeClient', () => { }) }) + it('openOrca keeps the last unreachable reason when later polls have no metadata', async () => { + const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-client-')) + writeMetadata(userDataPath, join(userDataPath, 'never-listened.sock'), 'token', process.pid) + vi.mocked(launchOrcaApp).mockImplementationOnce(() => { + rmSync(join(userDataPath, 'orca-runtime.json')) + }) + + const client = new RuntimeClient(userDataPath, 100) + + await expect(client.openOrca(100)).rejects.toMatchObject({ + code: 'runtime_open_timeout', + message: expect.stringContaining('never-listened.sock'), + data: { unreachableReason: { code: 'endpoint_missing' } } + }) + }) + it('openOrca waits for a reachable headless runtime to expose a desktop window', async () => { const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-client-')) const endpoint = join(userDataPath, 'runtime.sock') diff --git a/src/cli/runtime/client.ts b/src/cli/runtime/client.ts index de3051bd5ea..92afd58c35e 100644 --- a/src/cli/runtime/client.ts +++ b/src/cli/runtime/client.ts @@ -272,7 +272,7 @@ export class RuntimeClient { if (status.result.app.desktopWindowStatus === 'available') { return status } - lastReason = status.result.runtime.unreachableReason + lastReason = status.result.runtime.unreachableReason ?? lastReason await delay(250) } diff --git a/src/cli/runtime/local-runtime-unreachable-reason.test.ts b/src/cli/runtime/local-runtime-unreachable-reason.test.ts index 0f091c77ee3..83fcc2cd9b1 100644 --- a/src/cli/runtime/local-runtime-unreachable-reason.test.ts +++ b/src/cli/runtime/local-runtime-unreachable-reason.test.ts @@ -92,6 +92,13 @@ describe('classifyLocalRuntimeUnreachable', () => { ) }) + it('does not claim a permission-denied endpoint exists', () => { + const reason = classifyLocalRuntimeUnreachable(connectError('EACCES'), PIPE, 1000) + + expect(reason.message).not.toMatch(/\bexists\b/i) + expect(reason.message).toContain('OS denied') + }) + // The reported Windows 10 incident: the app process is alive, the pipe is not // openable from this process. The guidance must name the isolation possibilities // rather than telling the user to keep waiting. diff --git a/src/cli/runtime/local-runtime-unreachable-reason.ts b/src/cli/runtime/local-runtime-unreachable-reason.ts index 4ac231efc9a..d5204d61e6b 100644 --- a/src/cli/runtime/local-runtime-unreachable-reason.ts +++ b/src/cli/runtime/local-runtime-unreachable-reason.ts @@ -83,7 +83,7 @@ function describe( case 'endpoint_missing': return `Orca published the ${noun} ${endpoint}, but it does not exist for this process. Either the runtime shut its endpoint down, or this process cannot see it — a sandbox, container, or different user session each hide it this way. Run the CLI as the same user and outside any sandbox, or restart Orca.` case 'endpoint_permission_denied': - return `The ${noun} ${endpoint} exists but this process is not permitted to open it. Run the CLI as the same user that runs Orca, outside any sandbox that restricts ${noun} access.` + return `The OS denied this process access to the ${noun} ${endpoint}. Run the CLI as the same user that runs Orca, outside any sandbox that restricts ${noun} access.` case 'connection_refused': return `The ${noun} ${endpoint} refused the connection. Orca's runtime is most likely shutting down; restart Orca.` case 'connection_closed':