Skip to content

fix(agents): surface provider errors structurally instead of raw dumps#1653

Merged
wpfleger96 merged 5 commits into
mainfrom
worktree-wpfleger+structured-provider-errors
Jul 8, 2026
Merged

fix(agents): surface provider errors structurally instead of raw dumps#1653
wpfleger96 merged 5 commits into
mainfrom
worktree-wpfleger+structured-provider-errors

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

When a provider returns HTTP 404 (e.g. a Databricks account lacking access to goose-claude-opus-4-8), the user sees either a raw JSON-RPC dump or a misleading config nudge. The root cause is that AcpError::AgentError stringified the full JSON error object at the process boundary, destroying the typed code that buzz-agent already emits. The desktop then fell back to prefix string matching, which only recognized llm auth: and let everything else through as gray generic text.

This PR threads the JSON-RPC error code structurally from buzz-agent through buzz-acp to the desktop so the UI dispatches on numeric codes instead of fragile string patterns — for all four harness types (buzz-agent, goose, claude, codex), not just buzz-agent.

  • Add AgentError::LlmModelNotFound(String) variant with JSON-RPC code -32002, triggered on HTTP 404 in llm.rs:post() (shared across all providers)
  • Change AcpError::AgentError from String to { code: i64, message: String } and embed the code in the Display format ("Agent reported error (code N): ...") so it survives both the process boundary and log scraping
  • Include code in the turn_error observer event payload — works for any harness that emits JSON-RPC errors
  • Replace the buzz-agent-specific string-prefix heuristics in meaningful_agent_error_from_log with structured parsing of the (code N) field, making the log-scraping path harness-agnostic
  • Add last_error_code to ManagedAgentRecord / ManagedAgentSummary and code-based dispatch in friendlyAgentLastError() (switches on -32001 auth and -32002 model-not-found before the legacy string fallback)
  • Pass lastErrorCode through all three UI surfaces: agent card badge, management row, and session transcript — model-not-found now renders in red with actionable copy instead of gray raw text

When a provider returns HTTP 404 (e.g. Databricks model not accessible),
the error code was lost at the ACP process boundary and the desktop showed
raw JSON to the user. Thread the JSON-RPC error code from buzz-agent
through buzz-acp's observer payload to the desktop, so the UI dispatches
on numeric codes (-32001 auth, -32002 model-not-found) instead of fragile
string matching.
…s-agnostic

Embed the JSON-RPC code in AcpError::AgentError's Display format so the
log scraper can extract it for any harness, not just buzz-agent. Replace
the string-prefix heuristics with structured parsing of the (code N)
field. Add last_error_code to all ManagedAgentRecord construction sites,
fix cargo fmt / Biome formatting, and pass lastErrorCode at the second
UnifiedAgentsSection call site.
…guard

agentSessionTranscript.ts crossed its 1167-line ceiling. Move the
turn_error code coercion + copy fallback into the tested lib as a
helper, shrinking the transcript hot path back under the limit.
Adds `agent-error-state-screenshots.spec.ts` capturing the three
agent card error badge states added in the provider-error classification
work: model-not-found (code -32002), generic error, and side-by-side.

Extends the e2eBridge mock to carry `last_error_code` on seeded managed
agents so specs can drive the structured code path without string matching.
@wpfleger96

Copy link
Copy Markdown
Collaborator Author

🤖 Screenshots of the UI changes in this PR.

Model-not-found error badge (new structured classification)

A stopped agent whose provider returned a JSON-RPC -32002 code now shows a red CircleAlert badge with the tooltip "The configured model is not available — open agent settings and select a different one from the dropdown." instead of the raw error string from the log tail.

01-model-not-found-error-badge

Generic error badge (unchanged behavior, for contrast)

A stopped agent with an unclassified exit (no structured code) still shows the red CircleAlert badge, with the raw exit string as the tooltip. The badge appearance is identical — only the tooltip copy differs based on whether a structured code was present.

02-generic-error-badge

Both agents in context

Both error states side by side in the agents view, showing that every stopped agent with a lastError gets the badge regardless of classification.

03-agents-section-both-errors

wpfleger96 added a commit that referenced this pull request Jul 8, 2026
@wpfleger96 wpfleger96 merged commit 9b244ff into main Jul 8, 2026
29 checks passed
@wpfleger96 wpfleger96 deleted the worktree-wpfleger+structured-provider-errors branch July 8, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant