Skip to content

[fix] answer the workerd condition with the real async scope - #29

Merged
Thibaut-Fatus merged 1 commit into
mainfrom
fix/pack-scope-workerd-condition
Aug 31, 2026
Merged

Thibaut-Fatus merged 1 commit into
mainfrom
fix/pack-scope-workerd-condition

Conversation

@Thibaut-Fatus

Copy link
Copy Markdown
Collaborator

Why

#28 resolved the pack scope by condition, and a Cloudflare build asks for browser as well as workerd. With browser the only condition ahead of default, the worker bundle got the stack scope. Verified in kora-infra — app-website/dist/server/assets/worker-entry-*.js shipped:

class StackScope { ... }
function createPackScope() { return new StackScope(); }

That is the runtime the async scope exists for. A worker serves several runs concurrently in one isolate, and the stack scope drops the active pack at the first await — silently, with the right types and green tests, which is exactly the mis-binding #27 set out to prevent.

Caught by running the infra website locally and reading the built bundles, not by any check: the build succeeds either way.

What

workerd now precedes browser and answers with the node implementation. workerd exposes AsyncLocalStorage under nodejs_compat, which all three kora-infra workers set.

The order is the fix and nothing else would catch it losing, so the guard asserts it directly against the manifest — it fails if the two conditions are swapped (checked by swapping them).

Verified downstream

After mirroring the map in kora-infra:

  • app-website/dist/server — no StackScope; createPackScope() returns new AsyncLocalStorage() from node:async_hooks
  • app-website/dist/client — still no async_hooks reference
  • worker-engine (wrangler deploy --dry-run) — same, new AsyncLocalStorage()

tsbuild, 239 tests and prettier pass; lint unchanged (1 pre-existing warning).

#28 resolved the pack scope by condition, and a Cloudflare build asks for
`browser` as well as `workerd`. With `browser` the only condition listed ahead
of `default`, the worker bundle got the stack scope: verified in kora-infra,
where app-website's dist/server/assets/worker-entry-*.js shipped StackScope.

That is the runtime the async scope exists for. A worker serves several runs
concurrently in one isolate, and the stack scope drops the active pack at the
first await — silently, with the right types and green tests, exactly the
mis-binding #27 set out to prevent.

`workerd` now precedes `browser` and answers with the node implementation;
workerd exposes AsyncLocalStorage under nodejs_compat, which all three
kora-infra workers set.

The order is the whole fix and nothing else would catch it losing, so the guard
asserts it directly against the manifest — it fails if the two conditions are
swapped.

tsbuild, 239 tests and prettier pass; lint unchanged (1 pre-existing warning).
@Thibaut-Fatus
Thibaut-Fatus merged commit 6663ecc into main Aug 31, 2026
4 checks passed
@Thibaut-Fatus
Thibaut-Fatus deleted the fix/pack-scope-workerd-condition branch August 31, 2026 09:29
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.

1 participant