Version
main
Platform
Subsystem
stream
What steps will reproduce the bug?
import { merge } from 'node:stream/iter';
import { setTimeout } from 'node:timers/promises';
async function* pending() {
await new Promise(() => {});
}
const ac = new AbortController();
const iterator = merge(pending(), pending(), { signal: ac.signal })[Symbol.asyncIterator]();
setTimeout(100).then(() => ac.abort());
const result = await Promise.race([
iterator.next().then(
() => 'resolved',
(error) => `rejected: ${error.name}`,
),
setTimeout(500, 'hung'),
]);
console.log(result);
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
The pending iterator.next() should reject, likely with AbortError, after the signal is aborted.
What do you see instead?
The script prints hung.
The multi-source merge() path waits on an internal promise while source reads are pending, but aborting the signal does not resolve that waiter. Since no source settles, the next abort check is never reached.
Additional information
No response
Version
main
Platform
Subsystem
stream
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
The pending
iterator.next()should reject, likely withAbortError, after the signal is aborted.What do you see instead?
The script prints
hung.The multi-source
merge()path waits on an internal promise while source reads are pending, but aborting the signal does not resolve that waiter. Since no source settles, the next abort check is never reached.Additional information
No response