Skip to content

test(worker_threads): run #29211 regression tests concurrently

0fbebc1
Select commit
Loading
Failed to load commit list.
Open

Stop dispatching parent messages to self.onmessage in node:worker_threads workers #29215

test(worker_threads): run #29211 regression tests concurrently
0fbebc1
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed Apr 12, 2026 in 28m 55s

Code review found 1 important issue

Found 5 candidates, confirmed 2. See review comments for details.

Details

Severity Count
🔴 Important 1
🟡 Nit 0
🟣 Pre-existing 1
Severity File:Line Issue
🔴 Important src/js/node/worker_threads.ts:290-296 parentPort.on(fn) called twice orphans first callback, leaking listenerCount
🟣 Pre-existing src/js/node/worker_threads.ts:432-435 fake.addListener delivers raw MessageEvent instead of event.data

Annotations

Check failure on line 296 in src/js/node/worker_threads.ts

See this annotation in the file changed.

@claude claude / Claude Code Review

parentPort.on(fn) called twice orphans first callback, leaking listenerCount

When `parentPort.on('message', fn)` is called twice with the same `fn`, `injectFakeEmitter.on()` creates `callback2` and overwrites `fn[wrappedListener] = callback2`, losing the reference to `callback1`. Both callbacks are stored as separate entries in `trackedByListener` (keyed by the callback object, not by `fn`), so `listenerCount` reaches 2. When `parentPort.off('message', fn)` is called, it resolves `fn[wrappedListener] = callback2` and removes only `callback2`'s entry, decrementing `listen

Check notice on line 435 in src/js/node/worker_threads.ts

See this annotation in the file changed.

@claude claude / Claude Code Review

fake.addListener delivers raw MessageEvent instead of event.data

fake.addListener (lines 432-435) is wired directly to parentPortAddEventListener, so listeners receive a raw MessageEvent object instead of event.data, while fake.on goes through injectFakeEmitter's functionForEventType wrapper that extracts the data first. This is a pre-existing inconsistency — before this PR, addListener was self.addEventListener.bind(self), which also delivered raw events — that the PR carries forward unchanged. The fix is to wire fake.addListener to fake.on.bind(fake) so it