fix(canvas/chat): surface actionable error reason in chat banner + link to Activity tab (internal#212) #1550
Reference in New Issue
Block a user
Delete Branch "fix/canvas-surface-error-detail"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
useChatSocketnow forwardsACTIVITY_LOGGED.error_detail(introduced server-side in #1549) intoonSendErrorso the banner shows the provider's actionable reason — provider HTTP status + error code + human message — instead of the hardcoded opaque"Agent error (Exception) — see workspace logs for details."(which pointed at a workspace-logs tab that doesn't exist)ChatErrorBannercomponent with a workingView activity logbutton that callssetPanelTab("activity"), turning the dangling "see workspace logs" reference into a real affordance; the offline-onlyRestartbutton is preservederror_detailis absent the hook falls back to the legacy boilerplate so we never silently swallow a failure (boundary requirement from the task spec)Reason field shape (consumed)
From
ACTIVITY_LOGGED.payload.error_detail— a single string, already secret-safe (server-side scrubber + this trust boundary stays defensive). Examples the user will now see verbatim:Anthropic 403 oauth_org_not_allowed: Your organization has disabled Claude subscription access for Claude Code — use an Anthropic API key or ask your admin to enable access.kimi 401 invalid_api_key: provided key is wrongBefore / after
Before (internal#212):
("workspace logs" tab does not exist; nothing to click)
After:
(
View activity logswitches the side panel to the Activity tab)Test plan
vitest run— 285 tests across touched files green (3 new hook tests, 5 new banner tests)useChatSocket.test.tsx— forwards detail when present, falls back when absent, ignores cross-workspace eventsChatTab.errorBanner.test.tsx— renders reason verbatim, falls back to legacy boilerplate, navigates to Activity tab, Restart preserved offline, null message renders nothingtsc --noEmitclean on changed fileserror_detailfield to the broadcast payload). This canvas PR is forward-compatible — if it lands first, behavior is unchanged (fallback path).Refs: internal#212, feedback_surface_actionable_failure_reason_to_user
Depends-on: #1549
5-axis review on ChatTab error banner: correctness OK (graceful degrade to legacy boilerplate, render-nothing on null); readability OK (presentational component, clear prop contract); arch OK (extracts inline JSX to testable seam, navigates via setPanelTab from canvas store); security OK (no innerHTML, just text); perf OK (no socket subs, no state machine). Tests cover all four banner states including 'View activity log' click. APPROVED.
UX review: actionable affordance (View activity log → Activity tab) replaces the dangling 'see workspace logs' pointer-to-nowhere. Restart button preserved for offline path. internal#212 surface complete. APPROVED.