Skip to content

computer: Fix result sizes, dispose reasons and late calls in codemode modules - #302

Merged
ben-reitz merged 3 commits into
host-objectsfrom
browser/codemode-module-fixes
Nov 4, 2026
Merged

ben-reitz merged 3 commits into
host-objectsfrom
browser/codemode-module-fixes

Conversation

@ben-reitz

@ben-reitz ben-reitz commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Three fixes for #301, one commit each, so any of them can be taken on its own. They came up while porting the codemode:browser module (#299) onto createCodemodeModule().


If you want to review the code, i suggest doing it commit-by-commit as the fixes were committed one-by-one.


1. Measure plain results as plain data in replayable runs

In a replayable run, every codemode result was measured by encoding it with Cap'n Web, even plain JSON. That changed what fits inside the limits:

Result Before After
910 KB of HTML ❌ counted as 1,120 KB once escaped, over the 1 MiB limit ✅
DOM.getDocument on a 128-level page ❌ Serialization exceeded maximum allowed depth ✅

Results are now measured like replayable requests already are: plain data at its raw size, and only values like a Date by their encoding. When a value does contain one of those, the journal stores it whole with Cap'n Web, so measuring now also checks that it encodes. Otherwise a deep tree with a Date in it would fail later, when the journal stores it, instead of returning an error to the call.

2. Leave "disposed" out of a scoped context's dispose reasons

Only objects get "disposed", but a context's dispose was typed to get it too, which breaks the check:

if (end.reason !== "paused") end.log("…"); // TS2339: 'log' does not exist

dispose now takes CodemodeContextScopeEnd, which leaves "disposed" out.

3. Stop a method once its call has timed out

If a scoped context was slow to start, the caller was told the call timed out, but the method carried on after await ctx.session. The getter now checks the call's signal once the context starts, so every module gets the check without having to add it.


Devin Review

@ben-reitz ben-reitz added the allow-pr Allow a PR to remain open. label Nov 4, 2026
@changeset-bot

changeset-bot Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 832bfc8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

@pkg-pr-new

pkg-pr-new Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@cloudflare/computer@302

commit: 832bfc8

@ben-reitz
ben-reitz force-pushed the browser/codemode-module-fixes branch from fa2bc27 to f7ef356 Compare November 4, 2026 10:01
@ben-reitz
ben-reitz added this pull request to stack #303 November 4, 2026 10:26
@ben-reitz
ben-reitz removed this pull request from stack #303 November 4, 2026 10:46
@ben-reitz
ben-reitz force-pushed the browser/codemode-module-fixes branch from f7ef356 to 0a30691 Compare November 4, 2026 10:49
@ben-reitz
ben-reitz added this pull request to stack #304 November 4, 2026 10:50
In a replayable run, every codemode result was measured with Cap'n
Web's serialize(), even plain JSON, which the journal stores as JSON
anyway. Two results that a plain host module takes then failed: JSON
nested past 256 levels ("Serialization exceeded maximum allowed
depth"), such as a 128-level DOM.getDocument result, and text whose
JSON escaping pushed it over the byte limit.

Results are now measured the way replayable requests already are:
plain data by its raw size, and only richer values by their encoding.
A value with anything richer in it is still stored whole with Cap'n
Web's encoding, so measuring also checks that the whole value
encodes. A request or result too deep for the journal is then the
call's error, rather than a failure when the journal stores it.
Only objects can be released early, so a scoped context's dispose is
never told "disposed". Its end type still allowed it, so checking
`end.reason !== "paused"` didn't narrow to the reasons that have
log(), and the docs' example didn't compile.

dispose now takes CodemodeContextScopeEnd, which leaves "disposed"
out, and the test module drops its extra check.
A method that awaits a scoped context carried on after its call had
timed out or been cancelled, if the context was slow to start. The
caller had already been told the call failed, but the method could
still act, such as writing through a session it never should have used.

The scoped context's getter now checks the call's signal once the
context has started, so the method's await throws instead.
@ben-reitz
ben-reitz force-pushed the browser/codemode-module-fixes branch from 0a30691 to 832bfc8 Compare November 4, 2026 10:55
@ben-reitz
ben-reitz merged commit 832bfc8 into main Nov 4, 2026
22 checks passed
@ben-reitz
ben-reitz deleted the browser/codemode-module-fixes branch November 4, 2026 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

allow-pr Allow a PR to remain open.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant