Repository navigation
fix(native-chat): replace the Claude init error card with an actionable MCP connect warning - #28857
airematters wants to merge 2 commits into
Conversation
…ailed to connect The init frame lists every MCP server with its connect status, so one `status: 'failed'` entry made hasProviderError promote the whole session-start frame to an error-surface row. Skip payload failure inspection for inventory frame kinds (Claude `message:system:init`). Fixes stablyai#28856 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ls to connect The init frame no longer renders as an error dump, so report the one actionable fact it carries instead: a warning row naming each MCP server whose status is `failed`, pointing at `claude mcp list` for the reason. Init repeats every request cycle, so each server is reported once. Refs stablyai#28856 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to
|
|
thanks for the PR. Will review it soon |
ELI5
When one of your MCP servers can't connect, a Claude chat used to open with a scary red card full of raw JSON. Now it shows one plain warning: which server failed, that its tools are missing, and how to find out why.
What Changed
Before: any MCP server with
status: "failed"in Claude'ssystem:initframe turned the whole init frame into anerror-surfacefallback row: a redclaude · message:system:initcard whose disclosure is the raw frame (tool list, MCP servers, plugins…).After: the init frame never renders as a row. Instead, a
status/warningrow says e.g.:Mechanism:
provider-frame-disposition.ts: payload failure inspection (hasProviderError) is skipped for inventory frame kinds — today only Claudemessage:system:init. Its nestedstatusfields describe sub-resources, not the frame's outcome. Every other kind is still inspected.claude-mcp-connect-failure-row.ts, wired into the Claude provider fallback next to theinformationalrow: builds the warning frommcp_servers[].status === 'failed'. Init repeats every request cycle, so each server is reported once per session; a server that fails later gets its own row.needs-authis not reported.Why
The init frame is session inventory, so an error card for it is wrong, and the raw dump gives the user nothing to act on. Silently dropping it would hide a real problem (missing tools). Naming the server and pointing at
claude mcp list(which shows the connect error) makes it actionable. Init frames do not carry the error text itself, so the row cannot show the reason directly.Linked Issue
Fixes #28856
Visual Proof
Before: the red
claude · message:system:initcard described in #28856. After: the warning text above, asserted verbatim inclaude-mcp-connect-failure-row.test.ts. I have not captured an after-screenshot from a built app.Testing
I manually tested these changes locally
Automated tests added/updated, or explained why not below
provider-frame-disposition.test.ts: init with a failed server staysstatus-chrome; the same payload under another kind is stillerror-surface.claude-mcp-connect-failure-row.test.ts(throughcreateClaudeJournalTranslator): no row for connected / needs-auth; one row per newly failed server across repeated inits; one combined row for several failures in one init.Both new tests fail with their fix reverted.
vitestoversrc/main/native-chat+src/main/claude: 5609 passed.tsc -p config/tsconfig.node.json, oxlint, oxfmt,audit:anti-slop,check:max-lines-ratchetclean. Tested on macOS only; the change is platform-independent.AI Disclosure
Written with Claude Code (Claude Opus 5.5), reviewed by me.
Agent skill upstream boundary
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)🤖 Generated with Claude Code