Uh oh!
There was an error while loading. Please reload this page.
fix(desktop): localize expected errors - #4457
Conversation
53b08a5 to
b6ef648CompareorangeCatDeveloper
commented
Sep 1, 2026
Converting to draft: blocked on the copy-gate/architecture-ratchet collision described in #2672 (comment) — #4493 resolves the checker policy; this branch then rebases (and splits the global error mapper per review). Will mark ready once green. |
adf4f4a to
6b28e30Compare…cture ratchet (#4493) Two repository gates deadlocked. The locale policy (#2672) moves user-visible copy out of business files into src/renderer/locales/*-copy.ts catalogs, which adds an import edge; the renderer architecture ratchet forbids legacy files from growing their dependency count and rejects new AppShell-closure entries. #4457 failed CI on exactly that collision, and no placement of a catalog could satisfy both gates. Admit one dependency class instead of loosening the ratchet: a validated copy catalog, recognized structurally and re-verified on every run, never grandfathered. It must live under src/renderer/locales/*-copy.ts, carry the UiCatalog marker from @maka/core/ui-locale, have zero tracked capabilities by the checker's own metrics, and import bare package specifiers only, so it can never become a tunnel to renderer implementation. Admitted edges are excluded from the dependency-count ratchets and closure admission, and the ledger drops 26 budget entries that only existed for catalog imports. Root-entry files get no discount, and a catalog that grows a hook or a relative import loses admission immediately. The environment-capability predicate now counts identifiers only in value-reference positions, so a copy key named history or a parameter named location no longer reads as a browser global, and type-only imports and exports are not counted as runtime dependencies. Adversarial fixtures cover hook smuggling, implementation-import smuggling, a missing marker, dynamic imports and an unrelated dependency added beside a valid catalog. Part of #2672. Generated-by: Codex
13b0d58 to
ad06382Compare9050c08 to
47537fdCompare3c22d3a to
5925b9fCompare6d7be43 to
429a206CompareRaw 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
4e73a34 to
fd5b420CompareMove the redacted unexpected-failure diagnostics into @maka/core/redaction as reportUnexpectedOperation / unexpectedOperationFallback: copy catalogs may only hold bare package runtime imports, so shell-copy inlined the channel; the core helper removes the inline copy and lets operation-diagnostics delegate, keeping its public surface for the seven renderer importers. No behavior change: the same redacted console.error line, same fallbacks. Generated-by: Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
Code review follow-ups on the expected-errors PR: - Fold the duplicate attachmentIngestBlocked imports in attachment-ingest.ts and attachment-ingest-payload.ts into the existing @maka/core/attachments import. - Extract workBoardActionErrorText in work-board-panel.tsx (module-level, exported as a test seam): runAction and the presentation test now drive the exact same code-to-copy branch, so a panel mis-map fails the test instead of the test asserting its own re-implemented ternary. The expected-code lookup uses lookupCopy, so unknown/inherited keys keep the caller fallback. - The copy catalog stays import-free (copy catalogs may only hold bare package runtime imports), keeping the transport concern at the panel. Generated-by: Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
CI ratchet flagged the new @maka/core/ui-locale edge on work-board-panel.tsx as dependency debt (7 -> 8). Move the expected-code lookup into work-board-error-copy.ts as workBoardErrorCodeCopy: a validated copy catalog's bare-package runtime imports are exempt from pricing, so the panel sheds the new edge and the catalog's existing lookupCopy import becomes live again. No behavior change; the panel's workBoardActionErrorText keeps the same branch shape over the catalog helper. Generated-by: Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
hqhq1025
left a comment
There was a problem hiding this comment.
Reviewed exact head fe1190919fdd6ca246c4ca91ac8c423c184bd440.
This change replaces raw Desktop error text with localized copy and structured error handling across attachment ingestion, guest mounts, Work Board, collaboration, WorkHub, and Plan Mode. I found one P2 and one P3, so I do not think this head is ready to merge yet.
Validation: clean install; build:test; Desktop 2228/2228, Core 829/829, Runtime 3238 passed / 13 skipped; full Desktop typecheck; renderer architecture 101/101 including the base-relative gate; lint, format, ASF headers, diff check; Storybook build; and a clean patch-preserving merge onto current main 411512bd9. Full Storybook smoke had one product-sidebar-session-list--project-groups focus failure that reproduced on the exact base, while the base-only loading-catalog failure passed on this head. Hosted test and package were still running at publication. Native macOS/Windows behavior was not run locally.
Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.
| await refresh(); | ||
| } catch (cause) { | ||
| setError(message(cause)); | ||
| reportUnexpectedError('plan-mode:action', cause); |
There was a problem hiding this comment.
P2: Preserve the Runtime Host plan error code here instead of classifying every rejection as unexpected. plan.control and plan.turn.start legitimately return stable codes such as session_busy and operation_conflict (for an active root Turn or a stale proposal/store version), but the IPC path currently rejects and this catch logs the cause as unexpected and renders only operationFailed. A user who needs to wait or refresh therefore gets an unactionable “try again later” message. Please carry/map the structured code through the Desktop boundary and keep this generic path for genuinely unknown failures; the new test currently pins only the generic copy.
| // The reason token survives the Electron IPC wrapper. | ||
| const blocked = lookupCopy( | ||
| maps.attachmentIngestBlocked, | ||
| message.match(/attachment_ingest:([a-z_]+)/u)?.[1], |
There was a problem hiding this comment.
P3: This matcher is used by the global shell error presenter, not only attachment ingestion, and it accepts the marker anywhere in arbitrary error text. For example, new Error("Unable to open /tmp/attachment_ingest:count_limit/report.txt") is rendered as “At most 8 attachments per message” and skips unexpected-error diagnostics. Please recognize an exact IPC envelope/token (or use a structured error) and add a negative test for unrelated messages containing the substring.
Summary
Desktop surfaces rendered raw exception text as user-facing copy: a zh user hitting an expected failure saw an untranslated English
error.message, and unexpected exceptions could leak internal details into toasts and error banners. Producers (guest-session mounts, Work Board IPC, WorkHub controller, the composer attachment pipeline) now return machine-readable codes —{ code, params }where a message needs data — and the renderer maps codes through the locale catalogs. Expected failures throw a typedExpectedOperationError; everything else logs a redacted diagnostic and shows a localized fallback. This also deletes WorkHub's English-message-regex classifier and theMAKA_SESSION_READ_MESSAGES_ERRORmarker protocol.Per review, the global error mapper is split: each domain maps its own code union at its presenter; the
ExpectedOperationErrortransport and redacted diagnostics live once in the renderer'sapplication/contracts/operation-diagnosticsentry, now delegating toreportUnexpectedOperation/unexpectedOperationFallbackin@maka/core/redactionso copy catalogs (bare-import-only) and the renderer share one diagnostics channel. They are Desktop-only, and hosting them in@maka/uipulled the icon bundle into the main-process test bundles. The 11 attachment validations reject with stableattachment_ingest:<code>tokens that survive the Electron IPC wrapper, mapped at the sharedlocalizedShellErrorMessageentry — both locales previously lost these reasons to a generic fallback. The Runtime's 8 session-control guards emitsession_control_blocked:<code>tokens; today no in-repo caller reaches those guards (Desktop changes session settings throughsession.configuration.update, whose failures already carry protocol codes, and the CLI drives SessionManager only through the Runtime Host protocol), so the tokens stay as a typed, test-pinned contract for the future CLI-local path. A structured{ok, code}envelope for configuration setters and attachment failures is the follow-up.The WorkHub waiting summary is a complete catalog message in each locale, independent of the separately displayed status and retry paragraphs. This preserves existing output while letting future translations choose their own sentence structure.
Refs #2672
Verification
Before (zh UI, stale Work Board write / import over mount limit — raw English internals):
After (same failures; raw detail now only in the redacted console diagnostic):
Rebase/review follow-up (
2a7c11d6a) re-verified all of the above after moving the redacted unexpected-failure diagnostics into@maka/core/redaction(reportUnexpectedOperation/unexpectedOperationFallback) so the copy catalog and the renderer entry share one channel;operation-diagnosticskeeps its public surface for its seven renderer importers and delegates to the core helper. No behavior change.Review follow-up (
575f10b39+fe1190919): folded the duplicateattachmentIngestBlockedimports; extractedworkBoardActionErrorTextinwork-board-panel.tsx(exported test seam) so the presentation test drives the panel's real code-to-copy branch instead of re-implementing it — a panel mis-map now fails the test. The copy catalog stays free of transport imports (copy catalogs may only hold bare package runtime imports), and the expected-code lookup lives in the catalog asworkBoardErrorCodeCopyso the panel adds no dependency-debt edge. Re-verified against the PR base: desktop 2228/0, four typechecks 0 errors, renderer architecture ratchet (--base 411512bd9), biome clean.Earlier follow-up verification still holds: all 122 WorkHub tests pass, including three-locale summary assertions that remain valid when the separate paragraph copy changes; all 101 architecture-checker tests pass. The branch base is the current
main(411512bd9), so no prerequisite PRs remain; the draft blocker (#4493 checker policy) landed on 2026-09-02.AI use
Select exactly one:
Tool(s) and scope: Claude Code — analysis, implementation, tests, and this description, under the contributor's direction; the commit carries a
Generated-by: Claude Codetrailer.OpenCode implemented the complete waiting-summary catalog messages and added output tests; its follow-up commit carries
Generated-by: OpenCode. Claude Code landed the rebase/review follow-up (2a7c11d6a: single diagnostics channel in@maka/core/redaction,operation-diagnosticsdelegating), verified the branch against currentmain, and updated this description.Checklist