Skip to content

docs/08 misdocuments the shipped wire contract: exit event uses code not value, and EUNKNOWN_HASH is raised today #59

Description

@rajpreetcodes

Describe the bug

docs/08_capnweb_interface.md states it "now reflects shipped code in packages/rpc/", and the interface has no version negotiation ("hard wire breaks", docs/08:127-129), so implementers reasonably build clients from this doc. Two of its claims contradict the shipped code:

A. Exit event property name. docs/08_capnweb_interface.md:199-203 documents the ExecEvent exit variant as:

| { id: string; seq: number; name: "exit"; value: number; result?: unknown };

Shipped code uses code:

  • packages/rpc/src/interface.ts:153: { id: string; seq: number; name: "exit"; code: number; result?: unknown }
  • Emitters: packages/computerd/src/exec/runner.ts:233, :469; packages/computerd/src/exec/log.ts:215
  • The package's passing tests pin code: packages/rpc/tests/shell-and-composite.test.ts:78, 166, 272

Compiling a consumer written to the doc's shape against the shipped type:

error TS2339: Property 'value' does not exist on type
'{ id: string; seq: number; name: "exit"; code: number; result?: unknown; }'.

An untyped client reading event.value per the doc gets undefined for every exit code. Likely origin of the mix-up: the separate host HTTP line protocol (packages/computer/src/exec-wire.ts:34) legitimately uses value for exit; the confusion is live in the repo itself: packages/computer/tests/stub-soak-worker.ts:80 enqueues { name: "exit", value: 0 } into an rpc-typed ExecEvent stream.

B. EUNKNOWN_HASH claim inverted. docs/08:110-113 says "(planned: today the code returns an empty payload for missing hashes; EUNKNOWN_HASH via createWorkspaceError is the deferred fix)", and the error table at :323 marks it "(reserved, planned) ... not raised today". Both directions are false:

  • packages/dofs/src/sync/push.ts:22-24 throws createWorkspaceError("EUNKNOWN_HASH", ...) for a missing hash (comment at :9-12 notes the helper backs both wire directions)
  • packages/rpc/tests/wire.test.ts:298-326 is a passing test asserting err.code === "EUNKNOWN_HASH" survives the WebSocket round trip on fetchObjects of an unknown hash

A reader following the doc expects empty payloads (and doesn't handle the throw) while also being told to "branch on err.code" for a code the doc says is never raised.

Minor drift in the same file: :313-318 shows WireError with a detail?: unknown field absent from packages/rpc/src/interface.ts:167-170; :20-21 references a "stale /rpc comment at packages/rpc/src/client.ts:18" that no longer exists (that line now says /ws).

Expected behavior

The wire-contract doc matches packages/rpc/src/interface.ts: exit variant code: number; EUNKNOWN_HASH documented as raised today on both object-transfer paths; WireError snippet matches the shipped type; stale cleanup note removed.

Steps to reproduce

  1. Read docs/08_capnweb_interface.md:199-203 and :110-113/:323.
  2. Compare with packages/rpc/src/interface.ts:153 and packages/dofs/src/sync/push.ts:22-24.
  3. Run npm test --workspace @cloudflare/computer-rpc -- tests/wire.test.ts: the EUNKNOWN_HASH round-trip test passes, contradicting "not raised today".

Proposed fix

One-file docs change: change the exit variant to code: number; rewrite the fetchObjects comment and the EUNKNOWN_HASH table row to state it is raised today via createWorkspaceError; drop detail? from the WireError snippet (or add it to interface.ts if intended); delete the stale client.ts:18 note. Separately, packages/computer/tests/stub-soak-worker.ts:80 enqueuing { name: "exit", value: 0 } into an rpc-typed stream looks like the same confusion in code and may deserve a look.

Environment

  • cloudflare/computer at 76d9e75 (current main)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions