From 92ab31fb78b0237b2e13a536cc92d307e81d6d7f Mon Sep 17 00:00:00 2001 From: Sergio Date: Sun, 15 Mar 2026 17:52:35 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20drop=20bare=20Error:=20from=20error=20gu?= =?UTF-8?q?ard=20=E2=80=94=20too=20broad=20for=20monitoring=20prose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only match specific named JS exception types (TypeError, RangeError, SyntaxError, ReferenceError). Bare "Error:" is ambiguous — legitimate monitoring crons can start output with "Error: API latency exceeded threshold" which should not be suppressed. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../isolated-agent/delivery-dispatch.error-guard.test.ts | 8 ++++++-- src/cron/isolated-agent/delivery-dispatch.ts | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cron/isolated-agent/delivery-dispatch.error-guard.test.ts b/src/cron/isolated-agent/delivery-dispatch.error-guard.test.ts index fec7f8e17e8..29ce8a87bff 100644 --- a/src/cron/isolated-agent/delivery-dispatch.error-guard.test.ts +++ b/src/cron/isolated-agent/delivery-dispatch.error-guard.test.ts @@ -134,11 +134,15 @@ describe("isLikelyRawErrorOutput", () => { it("detects JS runtime exceptions", () => { expect(isLikelyRawErrorOutput("TypeError: Cannot read properties of undefined")).toBe(true); expect(isLikelyRawErrorOutput("RangeError: Maximum call stack size exceeded")).toBe(true); - expect(isLikelyRawErrorOutput("Error: ECONNREFUSED")).toBe(true); expect(isLikelyRawErrorOutput("SyntaxError: Unexpected token")).toBe(true); expect(isLikelyRawErrorOutput("ReferenceError: x is not defined")).toBe(true); }); + it("does not flag bare Error: prefix (could be legitimate monitoring prose)", () => { + expect(isLikelyRawErrorOutput("Error: ECONNREFUSED")).toBe(false); + expect(isLikelyRawErrorOutput("Error: API latency exceeded threshold")).toBe(false); + }); + it("detects common provider error messages in JSON", () => { const error = `{"message":"An error occurred while processing your request. You can retry your request."}`; expect(isLikelyRawErrorOutput(error)).toBe(true); @@ -248,7 +252,7 @@ describe("dispatchCronDelivery — error output guard", () => { }); it("preserves summary and outputText in the returned state even when skipping", async () => { - const errorText = "Error: ECONNREFUSED 127.0.0.1:18789"; + const errorText = "TypeError: Cannot read properties of undefined (reading 'send')"; const params = makeBaseParams({ synthesizedText: errorText }); const state = await dispatchCronDelivery(params); diff --git a/src/cron/isolated-agent/delivery-dispatch.ts b/src/cron/isolated-agent/delivery-dispatch.ts index 822754cf8d2..412612a9eba 100644 --- a/src/cron/isolated-agent/delivery-dispatch.ts +++ b/src/cron/isolated-agent/delivery-dispatch.ts @@ -289,7 +289,7 @@ async function retryTransientDirectCronDelivery(params: { */ const RAW_ERROR_OUTPUT_PATTERNS: readonly RegExp[] = [ /^\s*\{[\s\S]*"(?:type|error|code)":\s*"(?:error|server_error|invalid_request)/, - /^\s*(?:Error|TypeError|RangeError|SyntaxError|ReferenceError):/, + /^\s*(?:TypeError|RangeError|SyntaxError|ReferenceError):/, /^\s*\{[\s\S]*"(?:message|error)":\s*"An error occurred/, /\berror"?:\s*\{[\s\S]*"(?:type|code)":\s*"(?:server_error|invalid_request|rate_limit)/, ];