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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions