You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In packages/errors/src/is/index.ts:66-73, the is() function wraps a try { ... } catch {} block around the instanceof check to defend against a "cross-realm errors" scenario that has never been demonstrated in the codebase, the test suite, or any open issue. The block is silent (catch {} with no re-raise, no log, no comment beyond a one-line scenario hypothesis).
if(typeofErrorType==='function'&&'prototype'inErrorType){try{if(errorinstanceofErrorType){returntrue;}}catch{// instanceof can fail for cross-realm errors}}
This violates two rules:
Rule 0004 (No Speculative Defences): a guard must cover a demonstrated scenario, not a hypothetical one. The rule's source materials (Basarat Ali Syed, Ryan Cavanaugh, Vladimir Khorikov) explicitly carve out the == null idiom for absent values but offer no carve-out for try { } catch {} without a named bug reference.
Rule 0001 invariant 6 (no silent failures): an empty catch is exactly the smell the invariant forbids.
Located in:
packages/errors/src/is/index.ts:66-73
Problems with current implementation:
The cross-realm scenario has not been reported. No issue, no test, no production log references it.
The catch {} is silent: if instanceof ever does throw for a real reason, the user gets false back without any signal that the discrimination failed.
A reader has to determine whether the cross-realm scenario is real before they can trust the rest of the function. Every reader pays that tax.
Proposed State
After refactoring, the try { } catch {} is removed. The instanceof check is performed directly:
If a cross-realm bug is ever reported, the guard is added back with the bug number in a comment (per rule 0004's "Bug-driven addition only" enforcement clause). Until then, the code path is the cleanest expression of the contract.
Expected improvements:
Compliance with rule 0004 (no speculative defences).
Compliance with rule 0001 invariant 6 (no silent failures).
The reader can trust the is() function without first auditing the cross-realm hypothesis.
The test suite is honest about what it covers: today, the function discriminates same-realm errors only; that contract is documented, not hidden behind a swallowed catch.
Motivation
This refactoring is needed because:
The guard violates the project's stated discipline (rule 0004) and one of the ten absolute invariants (rule 0001 invariant 6).
The catch silently swallows any future throw from instanceof for a reason that has nothing to do with cross-realm errors (e.g. a malformed ErrorType argument, a V8 regression). The user is told false with no signal.
The cost of the guard (silent failure on the unhappy path) is paid forever; the benefit (defence against an unobserved scenario) is hypothetical.
Triggers for this work:
Working on feature X and encountered this (audit of packages/errors/src/ against the 16 architecture rules, August 2026)
Technical debt accumulation
Performance issues
Maintainability concerns
Risks
Potential risks:
Risk 1: If a consumer passes a Proxy-wrapped or revoked ErrorType, instanceof may throw. — Mitigation: this is a different category from "cross-realm"; rule 0004 says the guard should be added when the bug is reported, with the bug number. Until then, the throw propagates to the caller, which is the correct behaviour (the caller passed the malformed value; the function is not the right place to silently lie about the result).
Risk 2: Test suite regression if a test currently relies on the silent catch. — Mitigation: search tests/ for any test that passes a malformed ErrorType and asserts is() returns false. If found, the test is updated to assert the throw (the test is documenting the contract the rule now enforces).
Risk 3: Consumer code that depends on is() not throwing for any input. — Mitigation: the public function never threw before; the change preserves that contract for valid inputs. For invalid inputs (malformed ErrorType), the throw is the correct behaviour and matches TypeScript's own instanceof semantics.
Migration Plan
Migration approach:
Remove the try { ... } catch {} wrapper. Inline the instanceof check.
Update the inline comment to document the new contract: the function discriminates same-realm errors; cross-realm discrimination is out of scope until a bug is reported.
Search packages/errors/tests/ for any test that exercises the cross-realm path. Update or remove such tests.
Run the full test suite; document the change in the PR description.
Rollback plan: revert the PR. The change is local to is/index.ts.
Backward Compatibility
This refactoring maintains full backward compatibility
This refactoring has breaking changes (migration required)
This refactoring deprecates APIs (grace period needed)
Note: for valid inputs (which is the documented and tested contract), the function returns the same value as before. The behaviour change only affects malformed inputs, which the previous silent catch hid.
Scope
Files/Folders affected:
packages/errors/src/is/index.ts (lines 66-73)
packages/errors/tests/ (any test that exercises the silent catch)
Note: the component_affected dropdown is calibrated for a web template project, not for the @deessejs/errors package. The actual affected component is packages/errors.
Priority
p0: Critical - Blocking major work or causing bugs
p1: High - Important, should do soon
p2: Medium - Normal priority
p3: Low - Nice to have
Estimated Effort
effort: xs - Few minutes
effort: s - Half a day
effort: m - 1-2 days
effort: l - A week or more (needs breakdown)
Test Coverage Requirements
Existing tests cover this code area (will update)
Need to add new tests for this refactor
This area lacks test coverage (technical debt)
Integration tests will be added/updated
E2E tests will be added/updated
Testing Approach
Testing strategy:
Unit tests: confirm is(err, SomeError) returns true / false for same-realm discrimination (existing contract).
New test: confirm is(err, validErrorType) no longer swallows a hypothetical throw — if the inputs are valid, the function returns; if the inputs are invalid, the throw propagates (documented as the new contract).
Verification steps:
pnpm --filter @deessejs/errors test:run — existing tests pass; updated tests reflect the new contract.
pnpm --filter @deessejs/errors type-check — no regressions.
Current State
In
packages/errors/src/is/index.ts:66-73, theis()function wraps atry { ... } catch {}block around theinstanceofcheck to defend against a "cross-realm errors" scenario that has never been demonstrated in the codebase, the test suite, or any open issue. The block is silent (catch {}with no re-raise, no log, no comment beyond a one-line scenario hypothesis).This violates two rules:
== nullidiom for absent values but offer no carve-out fortry { } catch {}without a named bug reference.catchis exactly the smell the invariant forbids.Located in:
packages/errors/src/is/index.ts:66-73Problems with current implementation:
catch {}is silent: ifinstanceofever does throw for a real reason, the user getsfalseback without any signal that the discrimination failed.Proposed State
After refactoring, the
try { } catch {}is removed. Theinstanceofcheck is performed directly:If a cross-realm bug is ever reported, the guard is added back with the bug number in a comment (per rule 0004's "Bug-driven addition only" enforcement clause). Until then, the code path is the cleanest expression of the contract.
Expected improvements:
is()function without first auditing the cross-realm hypothesis.Motivation
This refactoring is needed because:
instanceoffor a reason that has nothing to do with cross-realm errors (e.g. a malformedErrorTypeargument, a V8 regression). The user is toldfalsewith no signal.Triggers for this work:
packages/errors/src/against the 16 architecture rules, August 2026)Risks
Potential risks:
Proxy-wrapped or revokedErrorType,instanceofmay throw. — Mitigation: this is a different category from "cross-realm"; rule 0004 says the guard should be added when the bug is reported, with the bug number. Until then, the throw propagates to the caller, which is the correct behaviour (the caller passed the malformed value; the function is not the right place to silently lie about the result).tests/for any test that passes a malformedErrorTypeand assertsis()returnsfalse. If found, the test is updated to assert the throw (the test is documenting the contract the rule now enforces).is()not throwing for any input. — Mitigation: the public function never threw before; the change preserves that contract for valid inputs. For invalid inputs (malformedErrorType), the throw is the correct behaviour and matches TypeScript's owninstanceofsemantics.Migration Plan
Migration approach:
try { ... } catch {}wrapper. Inline theinstanceofcheck.packages/errors/tests/for any test that exercises the cross-realm path. Update or remove such tests.Rollback plan: revert the PR. The change is local to
is/index.ts.Backward Compatibility
Note: for valid inputs (which is the documented and tested contract), the function returns the same value as before. The behaviour change only affects malformed inputs, which the previous silent catch hid.
Scope
Files/Folders affected:
packages/errors/src/is/index.ts(lines 66-73)packages/errors/tests/(any test that exercises the silent catch)Out of scope:
is/index.ts(covered by separate issues: P0 feat: implement is() type checking function #3 — redundant guard after narrowing; P0 feat: implement causes() function for cause chain traversal #5 —iindex naming; P0 chore: merge dev to main - core foundation complete #6 in spirit — registry pattern in inheritance walk).Component(s) Affected
Note: the
component_affecteddropdown is calibrated for a web template project, not for the@deessejs/errorspackage. The actual affected component ispackages/errors.Priority
Estimated Effort
Test Coverage Requirements
Testing Approach
Testing strategy:
is(err, SomeError)returnstrue/falsefor same-realm discrimination (existing contract).is(err, validErrorType)no longer swallows a hypothetical throw — if the inputs are valid, the function returns; if the inputs are invalid, the throw propagates (documented as the new contract).Verification steps:
pnpm --filter @deessejs/errors test:run— existing tests pass; updated tests reflect the new contract.pnpm --filter @deessejs/errors type-check— no regressions.Related Issues / Pull Requests
packages/errors/src/against rules 0001-0016, August 2026.docs/engineering/architecture/rules/0004-no-speculative-defences.md.docs/engineering/architecture/rules/0001-project-mindset.md(invariant 6: no silent failures).Relevant Documentation
docs/engineering/architecture/rules/0004-no-speculative-defences.mddocs/engineering/architecture/rules/0001-project-mindset.md(ten invariants)Pre-Submission Checklist