From b4e83ab3cc39d7def21b468dad61293ebb558d98 Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 2 Sep 2026 22:44:48 -0500 Subject: [PATCH] fix(runner): traverse ACPX error causes safely --- .../src/cli/acpx-sidecar-input.test.ts | 7 ++++ .../src/cli/acpx-sidecar-input.ts | 36 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/packages/paperclip-runner/src/cli/acpx-sidecar-input.test.ts b/packages/paperclip-runner/src/cli/acpx-sidecar-input.test.ts index f76e99e95e..85e9ee4d22 100644 --- a/packages/paperclip-runner/src/cli/acpx-sidecar-input.test.ts +++ b/packages/paperclip-runner/src/cli/acpx-sidecar-input.test.ts @@ -144,6 +144,10 @@ describe("ACPX sidecar input sequencing", () => { ], "runtime initialization cleanup failed", ); + const codedWrapper = Object.assign(new Error("opaque wrapper"), { + code: "ERR_UNCLASSIFIED_WRAPPER", + cause: missingModule, + }); expect(acpxSidecarErrorCode(missingModule)).toBe( "AGENT_STARTUP_FAILED.MODULE_NOT_FOUND", @@ -158,6 +162,9 @@ describe("ACPX sidecar input sequencing", () => { expect(acpxSidecarErrorCode(genericStartup)).toBe( "AGENT_STARTUP_FAILED.MODULE_NOT_FOUND", ); + expect(acpxSidecarErrorCode(codedWrapper)).toBe( + "AGENT_STARTUP_FAILED.MODULE_NOT_FOUND", + ); expect(acpxSidecarErrorCode(nestedHandshake)).toBe( "ACPX_SESSION_HANDSHAKE_TIMEOUT", ); diff --git a/packages/paperclip-runner/src/cli/acpx-sidecar-input.ts b/packages/paperclip-runner/src/cli/acpx-sidecar-input.ts index a8de5382eb..9376ee37f9 100644 --- a/packages/paperclip-runner/src/cli/acpx-sidecar-input.ts +++ b/packages/paperclip-runner/src/cli/acpx-sidecar-input.ts @@ -75,6 +75,7 @@ function directAcpxSidecarErrorCode(error: Error): string | null { ? "ACPX_SESSION_HANDSHAKE_TIMEOUT" : null; } + if (!STABLE_ACPX_SIDECAR_CODES.has(code)) return null; if (code !== "AGENT_STARTUP_FAILED") return code; const stderr = @@ -119,3 +120,38 @@ const GENERIC_ACPX_OUTPUT_CODES = new Set([ "RUNTIME", "USAGE", ]); + +const STABLE_ACPX_SIDECAR_CODES = new Set([ + "ACP_MODEL_UNSUPPORTED", + "ACP_SESSION_INIT_FAILED", + "AGENT_DISCONNECTED", + "AGENT_STARTUP_FAILED", + "AGENT_STARTUP_FAILED.EXIT_NONZERO", + "AGENT_STARTUP_FAILED.FILE_NOT_FOUND", + "AGENT_STARTUP_FAILED.INVALID_ARGUMENT", + "AGENT_STARTUP_FAILED.MODULE_NOT_FOUND", + "AGENT_STARTUP_FAILED.NO_STDERR", + "AGENT_STARTUP_FAILED.OTHER", + "AGENT_STARTUP_FAILED.PERMISSION_DENIED", + "AGENT_STARTUP_FAILED.SIGNAL", + "AGENT_STARTUP_FAILED.SYNTAX_ERROR", + "AGENT_STARTUP_FAILED.UNVERIFIED_MODULE", + "AUTH_REQUIRED", + "CLAUDE_ACP_SESSION_CREATE_TIMEOUT", + "SESSION_CONFIG_OPTION_REPLAY_FAILED", + "SESSION_MODEL_REPLAY_FAILED", + "SESSION_MODE_REPLAY_FAILED", + "SESSION_RESUME_REQUIRED", + "ACPX_EFFECTIVE_MODEL_MISMATCH", + "ACPX_MODEL_SELECTION_UNAVAILABLE", + "ACPX_MODEL_STATUS_UNAVAILABLE", + "ACPX_PERSISTED_SESSION_IDENTITY_MISMATCH", + "ACPX_PERSISTED_SESSION_MISSING", + "ACPX_RUNTIME_ADMISSION_VERIFICATION_TIMEOUT", + "ACPX_SESSION_ENSURE_FAILED", + "ACPX_SESSION_ENSURE_NON_ERROR", + "ACPX_SESSION_ENSURE_TYPE_ERROR", + "ACPX_SESSION_HANDSHAKE_TIMEOUT", + "ACPX_SIDECAR_STATUS_READ_TIMEOUT", + ...GENERIC_ACPX_OUTPUT_CODES, +]);