From eaeced477421fc413473bbba39affb3c849d0179 Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Mon, 6 Apr 2026 18:20:11 -0700 Subject: [PATCH] fix(gsd): extract real error from message content when errorMessage is useless MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When errorMessage is uninformative (e.g. "success", "ok", "error"), fall back to the assistant message text content to surface the real provider error like "Invalid API key · Please run /login". Fixes #3588 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../extensions/gsd/bootstrap/agent-end-recovery.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts b/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts index ac8737d09..c5b9555a3 100644 --- a/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +++ b/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts @@ -95,8 +95,17 @@ export async function handleAgentEnd( return; } if (lastMsg && "stopReason" in lastMsg && lastMsg.stopReason === "error") { - const errorDetail = "errorMessage" in lastMsg && lastMsg.errorMessage ? `: ${lastMsg.errorMessage}` : ""; - const errorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : ""; + // #3588: errorMessage can be useless (e.g. "success") while the real error + // is in the assistant message text content. Fall back to content when + // errorMessage looks uninformative. + const rawErrorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : ""; + const isUseless = !rawErrorMsg || /^(success|ok|true|error|unknown)$/i.test(rawErrorMsg.trim()); + let errorMsg = rawErrorMsg; + if (isUseless && "content" in lastMsg && Array.isArray(lastMsg.content)) { + const textBlock = lastMsg.content.find((b: any) => b.type === "text" && b.text); + if (textBlock) errorMsg = (textBlock as any).text.slice(0, 300); + } + const errorDetail = errorMsg ? `: ${errorMsg}` : ""; const explicitRetryAfterMs = ("retryAfterMs" in lastMsg && typeof lastMsg.retryAfterMs === "number") ? lastMsg.retryAfterMs : undefined; // ── 1. Classify ──────────────────────────────────────────────────────