fix(desktop): return expected failures as codes across IPC - #4878
Draft
orangeCatDeveloper wants to merge 3 commits into
Draft
fix(desktop): return expected failures as codes across IPC#4878orangeCatDeveloper wants to merge 3 commits into
orangeCatDeveloper wants to merge 3 commits into
Conversation
orangeCatDeveloper
force-pushed
the
fix/ipc-expected-failure-envelope
branch
3 times, most recently
from
September 6, 2026 11:03
705a9ac to
50629d3
Compare
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. Plan controls and work-board actions carry those codes across IPC in a structured envelope, since Electron strips custom fields off thrown Errors. Generated-by: Claude Code
orangeCatDeveloper
force-pushed
the
fix/ipc-expected-failure-envelope
branch
from
September 6, 2026 21:12
13f4497 to
3af86a4
Compare
Squash of the stacked increment, rebased onto fix/desktop-error-codes (apache#4457) after its rewrite onto main: typed AttachmentIngestBlockedError with the attachment_blocked envelope, ExpectedOperationError across the preload and session-settings surface, typed session-configuration transition errors in the Runtime, and the sessionSettingsActions updateFailures catalog per locale. localizedShellErrorMessage no longer parses any token. Generated-by: Claude Code Generated-by: OpenCode
orangeCatDeveloper
force-pushed
the
fix/ipc-expected-failure-envelope
branch
from
September 6, 2026 21:32
3af86a4 to
8aaadc1
Compare
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 free
to 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?