fix(itx): getItxErrorCode must not consult error.name — capnweb drops it in transit#1462
Merged
Merged
Conversation
…s in transit Every preview e2e run on main has been red since #1456 merged: its own new e2e test ("kernel errors cross capnweb as ItxError-shaped errors with codes") failed on the PR's own preview run and on every full preview run since, asserting error.name === "ItxError" while the wire delivers "Error". capnweb 0.8.0's receiver maps only builtin error names to classes; an unknown name like "ItxError" reconstructs as plain `Error`, and the props loop skips `name` on both ends — so the name never crosses a capnweb session (Workers RPC, by contrast, preserves it). The unit-test simulation of the crossing reattached `name` by hand, encoding the wrong model, which is why unit tests stayed green while the real wire failed. Detection now rides on the closed five-code set alone: getItxErrorCode accepts any object whose `code` is one of the five, name not consulted. The five-code set membership is what keeps Node's ECONNREFUSED-style coded errors out. The e2e test now asserts the real wire shape (plain Error + code + details, detected via getItxErrorCode), and the simulation helper matches what capnweb actually does. Verified against a live preview deployment (preview_6): the previously failing test passes; the Workers-RPC boundary suite (which legitimately keeps `name`) still passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…yping # Conflicts: # apps/os/src/itx/e2e/itx.e2e.test.ts # apps/os/src/itx/errors.ts
jonastemplestein
added a commit
that referenced
this pull request
Jun 10, 2026
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.
Narrowed after #1447 landed: that PR fixed the e2e test's assertions (asserting the real wire shape,
name === "Error"+ rawcode), which unblocks preview e2e on main. What it did NOT fix is the detection helper itself —getItxErrorCodestill requireserror.name === "ItxError", and capnweb 0.8.0 drops custom error names in transit (the receiver maps only builtin names to classes; the props loop skipsnameon both ends). So after any capnweb hop, every runtime consumer of the helper — react hooks,stream-tail,isItxAccessErrorretry predicates — fails to recognize kernel errors and treats NOT_FOUND/FORBIDDEN like connection noise.Probed against a live preview deployment:
Fix
getItxErrorCodeduck-types on the closed five-code set alone;nameis not consulted (it cannot be, after capnweb). Set membership keeps foreign coded errors (ECONNREFUSED, …) out. The unit-testsimulateCapnwebCrossinghelper no longer reattachesnameby hand — that hand-modeled reattachment is exactly how the original bug stayed green in unit tests while failing on the real wire. Docs inerrors.tsupdated to match (merged with #1447's wording).Verification
Error+code) is now detected; unit tests assert itpnpm test:itx-stream-subscribe(real Workers RPC boundary, which legitimately preservesname) still passes🤖 Generated with Claude Code
Note
Medium Risk
Changes shared error-classification used for retry vs access-failure handling across capnweb clients; behavior widens slightly (code-only shapes now match) but is constrained by the five-code allowlist.
Overview
getItxErrorCodeno longer requireserror.name === "ItxError"— it treats any object whosecodeis one of the five itx codes as an ItxError. That matches errors after a capnweb RPC crossing, where the receiver rebuilds a plainErrorand drops the name whilecode/detailsstill arrive as own props.Docs on
getItxErrorCodeinerrors.tsnow spell out whynamemust not be used and how the closed code set avoids colliding with othercode-bearing errors (e.g.ECONNREFUSED).Unit tests were aligned with real capnweb:
simulateCapnwebCrossingno longer re-attachesname, duck-typed cases use plainError+codeonly, and rejection cases use foreign codes instead of wrongname.Reviewed by Cursor Bugbot for commit 5c3e6d3. Bugbot is set up for automated code reviews on this repo. Configure here.