Skip to content

feat(kernel-errors): standardize kernel errors observable in vat-land#913

Open
rekmarks wants to merge 5 commits intomainfrom
rekm/standardize-kernel-errors
Open

feat(kernel-errors): standardize kernel errors observable in vat-land#913
rekmarks wants to merge 5 commits intomainfrom
rekm/standardize-kernel-errors

Conversation

@rekmarks
Copy link
Copy Markdown
Member

@rekmarks rekmarks commented Apr 1, 2026

Summary

Kernel errors surfaced to vats as promise rejections previously had no consistent format — some were plain strings, some Error objects, with no way for vat code to programmatically identify or categorize them.

This PR introduces a machine-readable error format: [KERNEL:<CODE>] detail for expected errors (vat code can handle gracefully) and [KERNEL:VAT_FATAL:<CODE>] detail for fatal errors (vat gets terminated).

  • Add vat-observable-errors.ts to @metamask/kernel-errors with KernelErrorCode types, KERNEL_ERROR_PATTERN regex, and isKernelError/getKernelErrorCode/isFatalKernelError detection utilities
  • Add makeKernelError and makeFatalKernelError helpers to kernel-marshal.ts, importing shared types from @metamask/kernel-errors
  • Migrate all error sites across KernelRouter, RemoteManager, VatHandle, VatSyscall, and KernelServiceManager
  • Remove makeError (no remaining callers)
  • Remove kernel-internal details (peer IDs) from error messages sent to vats
  • Rewrite @metamask/kernel-errors README to delineate the three distinct error categories in the package (error classes, stream marshalling, vat-observable error codes) and explain why they exist as separate systems

Note: Four sites previously used kser('string') which serialized a plain string as the rejection value. These now use makeKernelError(...) which serializes an Error object. This is an intentional wire-format change — vat code that deserialized the rejection and checked typeof reason === 'string' would need updating.

Testing

New unit tests cover the detection utilities (vat-observable-errors.test.ts) and factory functions (kernel-marshal.test.ts), including round-trip verification through the @metamask/kernel-errors detection utilities. All existing unit tests in @metamask/ocap-kernel and integration tests in @ocap/kernel-test pass with updated assertions matching the new [KERNEL:*] format.


Note

Medium Risk
Changes the wire format of promise rejections visible to vats (many string/opaque errors become serialized Errors with [KERNEL:*] prefixes), which may break downstream error handling and affects multiple kernel routing/termination paths.

Overview
Standardizes vat-observable kernel promise rejections to a machine-readable message format: expected errors as [KERNEL:<CODE>] ... and fatal errors as [KERNEL:VAT_FATAL:<CODE>] ....

Adds @metamask/kernel-errors utilities and types (KernelErrorCode, KERNEL_ERROR_PATTERN, isKernelError, getKernelErrorCode, isFatalKernelError) plus tests, and updates docs to clearly separate error-class vs stream-marshalling vs vat-observable error domains.

Migrates kernel sites that surface errors to vats (KernelRouter, RemoteManager, KernelServiceManager, VatHandle, VatSyscall) to use new makeKernelError/makeFatalKernelError helpers (replacing ad-hoc kser('string')/kser(Error)), introduces new explicit codes like OBJECT_REVOKED, OBJECT_DELETED, BAD_PROMISE_RESOLUTION, ENDPOINT_UNREACHABLE, CONNECTION_LOST, PEER_RESTARTED, VAT_TERMINATED, DELIVERY_FAILED, and updates unit/e2e assertions accordingly.

Written by Cursor Bugbot for commit 9538b10. This will update automatically on new commits. Configure here.

rekmarks and others added 3 commits April 1, 2026 16:43
Introduce a machine-readable error format for kernel errors surfaced to
vats as promise rejections: `[KERNEL:<CODE>] detail` for expected errors
and `[KERNEL:FATAL:<CODE>] detail` for fatal ones.

- Add `kernel-error.ts` to `@metamask/kernel-errors` with
  `ExpectedKernelErrorCode`, `FatalKernelErrorCode`, `KernelErrorCode`
  types, `KERNEL_ERROR_PATTERN` regex, and `isKernelError`,
  `getKernelErrorCode`, `isFatalKernelError` detection utilities
- Add `makeKernelError` and `makeFatalKernelError` to `kernel-marshal.ts`,
  importing the shared types from `@metamask/kernel-errors`
- Migrate all 17+ error sites in KernelRouter, RemoteManager, VatHandle,
  VatSyscall, and KernelServiceManager to the new helpers
- Update all affected test assertions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fatal kernel errors terminate the offending vat, not the kernel itself.
Rename the infix from FATAL to VAT_FATAL to reflect this:
`[KERNEL:VAT_FATAL:<CODE>] detail`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Import FatalKernelErrorCode in VatSyscall.ts instead of inline union
- Add unit tests for makeKernelError and makeFatalKernelError with
  round-trip verification through kernel-errors detection utilities

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rekmarks rekmarks requested a review from a team as a code owner April 1, 2026 23:56
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 78.42%
⬆️ +0.13%
8509 / 10850
🔵 Statements 78.24%
⬆️ +0.13%
8645 / 11049
🔵 Functions 75.88%
⬆️ +0.03%
1983 / 2613
🔵 Branches 76.12%
⬆️ +0.05%
3651 / 4796
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/kernel-errors/src/index.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
packages/kernel-errors/src/vat-observable-errors.ts 100% 100% 100% 100%
packages/ocap-kernel/src/KernelRouter.ts 93.33%
⬆️ +8.89%
77.61%
⬆️ +4.48%
100%
🟰 ±0%
93.33%
⬆️ +8.89%
110, 174, 191, 262, 273, 317, 363, 378, 381
packages/ocap-kernel/src/KernelServiceManager.ts 92.15%
⬇️ -1.72%
77.27%
⬇️ -11.61%
100%
🟰 ±0%
92.15%
⬇️ -1.72%
195-202
packages/ocap-kernel/src/liveslots/kernel-marshal.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
packages/ocap-kernel/src/remotes/kernel/RemoteManager.ts 98.88%
⬆️ +1.11%
100%
🟰 ±0%
95.65%
🟰 ±0%
98.88%
⬆️ +1.11%
377-379
packages/ocap-kernel/src/vats/VatHandle.ts 90%
🟰 ±0%
85.71%
🟰 ±0%
100%
🟰 ±0%
90%
🟰 ±0%
311, 362-367, 376-382
packages/ocap-kernel/src/vats/VatSyscall.ts 100%
🟰 ±0%
95.45%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
Generated in workflow #4174 for commit 9538b10 by the Vitest Coverage Report Action

@grypez
Copy link
Copy Markdown
Contributor

grypez commented Apr 2, 2026

Formalizing these errors seems good, but why not use the existing kernel-errors/src/errors convention?

- Rename kernel-error.ts to vat-observable-errors.ts to clarify that
  these are errors observed by vat code as promise rejections, distinct
  from the kernel-side error classes and stream error marshalling
- Migrate last makeError call in VatHandle.ts to makeFatalKernelError
- Remove makeError (no remaining callers)
- Rewrite README to delineate the three error categories and explain
  why they exist as separate systems

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rekmarks
Copy link
Copy Markdown
Member Author

rekmarks commented Apr 2, 2026

- Add ENDPOINT_UNREACHABLE and DELIVERY_FAILED test cases to
  KernelRouter tests
- Tighten OBJECT_DELETED and BAD_PROMISE_RESOLUTION assertions from
  expect.anything() to check for specific error codes
- Verify CONNECTION_LOST in handleRemoteGiveUp rejection payload
- Verify PEER_RESTARTED in handleIncarnationChange rejection payload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rekmarks rekmarks requested a review from sirtimid April 2, 2026 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants