Skip to content

fix: accept Node.js Timeout objects as the Delay timer handle - #1095

Open
PedroRosalba wants to merge 1 commit into
cloudflare:mainfrom
PedroRosalba:fix/delay-timeout-handle
Open

PedroRosalba wants to merge 1 commit into
cloudflare:mainfrom
PedroRosalba:fix/delay-timeout-handle

Conversation

@PedroRosalba

Copy link
Copy Markdown

Problem

From compatibility date 2026-08-04, nodejs_compat is on by default and implies enable_nodejs_global_timers, so setTimeout returns a Node.js Timeout object instead of a number. Delay bound it through web-sys as Result<i32, JsValue> and unwrapped it. The type-checked glue of worker-build --dev rejects the object (expected a number argument, found object), so every Delay panicked in dev builds; release glue coerces the object to its id, which is why only dev builds were affected.

Fix

Bind setTimeout / clearTimeout directly with an opaque JsValue handle and hand the same handle back on drop. This works for both the numeric and the Timeout handle, and on both compatibility date ranges.

Tests

Adds delay.spec.ts, which boots the test worker on a second Miniflare instance at compatibility date 2026-08-04 next to the default one, plus a drop-path route that races two delays. Fails on main under --dev, passes with this change.

Tested on macOS (Apple Silicon) only.

Fixes #1086

From compatibility date 2026-08-04 `nodejs_compat` is on by default, which
implies `enable_nodejs_global_timers`: `setTimeout` returns a Node.js
`Timeout` object instead of a number. `Delay` bound it through web-sys as
`Result<i32, JsValue>` and unwrapped, and the type-checked glue of
`worker-build --dev` rejected the object ("expected a number argument,
found object"), so every `Delay` panicked in dev builds. Release glue
coerced the object to its id, which is why only dev builds were affected.

Bind `setTimeout`/`clearTimeout` directly with an opaque `JsValue` handle
and hand the same handle back on drop, which works for both handle kinds.

Add a `delay.spec.ts` that runs the test worker on a second Miniflare
instance at compatibility date 2026-08-04 next to the default one, with a
drop-path route that races two delays.

Fixes cloudflare#1086
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.

[BUG] Delay panics in a --dev build from compat date 2026-08-04 (setTimeout returns an object)

1 participant