Skip to content

stream/iter: BroadcastWriter writev methods accept non-sequence chunks #63299

@trivikr

Description

@trivikr

Version

26.1.0

Platform

macOS 26.5.0

Subsystem

stream

What steps will reproduce the bug?

import assert from "node:assert/strict";
import { broadcast, text } from "node:stream/iter";

// Bug: BroadcastWriter.writev() accepts a string instead of validating that
// chunks is a valid sequence. It treats the string as array-like and writes
// each character as a chunk.
// Expected: writer.writev('abc') should throw ERR_INVALID_ARG_TYPE.
{
  const { writer, broadcast: bc } = broadcast();
  const consumer = bc.push();

  await writer.writev("abc");
  await writer.end();

  assert.equal(await text(consumer), "abc");
  console.log("BUG: writer.writev('abc') succeeded and wrote 'abc'");
}

// Bug: BroadcastWriter.writevSync() accepts a string instead of validating that
// chunks is a valid sequence, returns true, and writes the string contents.
// Expected: writer.writevSync('abc') should throw ERR_INVALID_ARG_TYPE.
{
  const { writer, broadcast: bc } = broadcast();
  const consumer = bc.push();

  assert.equal(writer.writevSync("abc"), true);
  writer.endSync();

  assert.equal(await text(consumer), "abc");
  console.log("BUG: writer.writevSync('abc') returned true and wrote 'abc'");
}

// Bug: BroadcastWriter.writev() accepts a non-sequence number. Because numbers
// have no length, convertChunks() creates an empty array and the write resolves.
// Expected: writer.writev(42) should throw ERR_INVALID_ARG_TYPE.
{
  const { writer } = broadcast();

  await assert.doesNotReject(writer.writev(42));
  writer.endSync();

  console.log("BUG: writer.writev(42) resolved instead of throwing");
}

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

writer.writev('abc') should throw ERR_INVALID_ARG_TYPE.
writer.writevSync('abc') should throw ERR_INVALID_ARG_TYPE.
writer.writev(42) should throw ERR_INVALID_ARG_TYPE.

What do you see instead?

No errors, and it prints statements

BUG: writer.writev('abc') succeeded and wrote 'abc'
BUG: writer.writevSync('abc') returned true and wrote 'abc'
BUG: writer.writev(42) resolved instead of throwing

Additional information

No response

Metadata

Metadata

Assignees

Labels

streamIssues and PRs related to the stream subsystem.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions