From 7294e76929e2cc18ff15c8610158d1550b0571ce Mon Sep 17 00:00:00 2001 From: Jiang Bohan Date: Mon, 9 Feb 2026 15:51:32 +0800 Subject: [PATCH] fix(agent): only emit agent_error for auth issues, not runtime 400 errors Previously all agent errors (including 400 invalid_request_error) were emitted as agent_error events, triggering the UI error banner and interrupting the chat flow. Now only auth-related errors (401, no API key) emit agent_error so the "Configure" banner appears. Runtime errors like 400 are still shown as chat messages but don't block the agent. Co-Authored-By: Claude Opus 4.6 --- src/agent/async-agent.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/agent/async-agent.ts b/src/agent/async-agent.ts index 8015b95e..7d322d14 100644 --- a/src/agent/async-agent.ts +++ b/src/agent/async-agent.ts @@ -73,15 +73,25 @@ export class AsyncAgent { if (result.error) { console.error(`[AsyncAgent] Agent run error: ${result.error}`); this.channel.send({ id: uuidv7(), content: `[error] ${result.error}` }); - this.agent.emitError(result.error); + // Only emit agent_error for HTTP 401 from the LLM provider so the + // UI shows the "Configure" banner. All other errors (400, tool errors, + // etc.) should flow back to the agent for self-recovery. + if (/\b401\b/.test(result.error)) { + this.agent.emitError(result.error); + } } }) .catch((err) => { const message = err instanceof Error ? err.message : String(err); console.error(`[AsyncAgent] Agent run exception: ${message}`); this.channel.send({ id: uuidv7(), content: `[error] ${message}` }); - // Also emit through subscriber mechanism so IPC listeners receive the error - this.agent.emitError(message); + // Only emit agent_error for HTTP 401 from the LLM provider so the + // UI shows the "Configure" banner. All other errors (400, tool errors, + // etc.) should flow back to the agent for self-recovery. + const errMsg = err instanceof Error ? err.message : String(err); + if (/\b401\b/.test(errMsg)) { + this.agent.emitError(message); + } }) .finally(() => { this.pendingWrites = Math.max(0, this.pendingWrites - 1);