Uh oh!
There was an error while loading. Please reload this page.
fix(desktop): return expected failures as codes across IPC - #4878
Draft
orangeCatDeveloper wants to merge 6 commits into
Draft
fix(desktop): return expected failures as codes across IPC#4878orangeCatDeveloper wants to merge 6 commits into
orangeCatDeveloper wants to merge 6 commits into
Conversation
Raw exception text no longer reaches the UI: expected failures carry machine-readable codes (with params where needed) that the renderer maps through locale catalogs, and unexpected failures show a localized fallback while redacted diagnostics go to the console. WorkHub waiting summaries are full per-locale templates so they translate independently of the status and retry paragraphs. Generated-by: Claude Code Claude-Session: https://claude.ai/code/session_01AqdSkg56F2x55wEGRWvzcB
Generated-by: OpenCode
Keep message-free WebSearch failures valid at the canonical result boundary so settlement cannot mark them successful. Retain redacted Work Board corruption details without exposing them in product copy. Generated-by: OpenCode
The session-control and attachment-ingest code unions lived in the renderer catalog while the Runtime and preload threw string literals, so a new producer code could miss the catalog without a type error. Generated-by: Claude Code
Desktop changes session settings through the Runtime Host's session.configuration.update, whose failures already carry protocol codes; the SessionManager guards that emit session_control_blocked tokens run only on the CLI's local runtime. Generated-by: Claude Code
Session-setting writes and attachment ingest reported expected failures by throwing, and Electron keeps only the message across both IPC boundaries, so the renderer either parsed a token out of the text or fell back to generic copy. The setters now answer with an update envelope carrying the Runtime Host's own error code, attachment validation failures ride the existing submit envelope, and the renderer adapters turn a failed envelope into ExpectedOperationError for the presenters. Generated-by: Claude Code
orangeCatDeveloperforce-pushed
the
fix/ipc-expected-failure-envelope
branch
from
September 6, 2026 02:46
3e17d5b to
5ac47d9Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stacked on #4457; review the last commit.
Changing a task's permission mode, plan mode, orchestration, or model while it is busy shows the generic "cannot change right now" toast in every locale, and an attachment that fails validation is reported by parsing an
attachment_ingest:<code>token out of the error text.Root cause: both Desktop serialization boundaries keep only
Error.message. The Runtime Host already answerssession.configuration.updatewith a structured code (session_busy,operation_conflict, …) and the Desktop client surfaces it asRuntimeHostOperationError.code, but the main-process IPC handler rethrows, so Electron hands the rendererError invoking remote method 'sessions:setPermissionMode': Error: Session has a pending Interactionand the presenter can only fall back.The fix moves expected failures into return values. The five session-setting handlers answer
{ ok: true, session } | { ok: false, code }, wherecodeis the Host's own code narrowed to the four a user can act on; unexpected failures still throw. Attachment validation raises a typedAttachmentIngestBlockedErrorthat preload and main turn into thesubmitMessage/sendenvelope's newattachment_blockedvariant. On the renderer side the platform adapters unwrap a failed envelope intoExpectedOperationError(code), so the existing intent hook andsessionSettingFailureCopykeep their shape and map the code through a newupdateFailurescatalog.localizedShellErrorMessageno longer parses any token.Boundaries: the protocol is untouched, so there is no Host version skew. The Runtime's
session_control_blockedtokens stay for the CLI's local runtime, which is their only consumer. The plan-mode write inapp-shellnow goes through the session-settings port rather thanwindow.makadirectly, which is what keeps the root-file ratchet flat.Refs #2672
Verification
Rendered-output assertions in
expected-error-presentation.test.ts:Before, a
session_busyanswer reached the toast as the locale fallback; after,sessionSettingFailureCopy('zh-CN', 'permission', new ExpectedOperationError('session_busy')).descriptionrenders当前任务正在运行或有交互待处理,等结束后再改设置。and theencatalog rendersA task is running or waiting on you. Change this setting after it settles.Not run: Electron e2e, packaged build.
AI use
Select exactly one:
Tool(s) and scope: Claude Code traced the failure path, wrote the envelope types, the main/preload/renderer changes, the catalog copy, and the tests; the design decision to keep the protocol untouched and the copy wording were reviewed by hand. The commit carries
Generated-by: Claude Code.Checklist
Does this PR entail a change in behavior?