denoland/deno · error · RangeError

${prefix}: When underlying source is "bytes", strategy.size

Error message

${prefix}: When underlying source is "bytes", strategy.size must be 'undefined'

What it means

RangeError from the ReadableStream constructor: when underlyingSource.type is 'bytes', the queuing strategy must not define a size function (strategy.size !== undefined). Byte streams measure chunks by byte length internally and use a byte-count highWaterMark (default 0), so a custom size would be meaningless; the spec forbids it rather than ignoring it.

Source

Thrown at ext/web/06_streams.js:6081

        strategy,
        prefix,
        "Argument 2",
      )
      : {};

    const underlyingSourceDict = underlyingSource !== undefined
      ? webidl.converters.UnderlyingSource(
        underlyingSource,
        prefix,
        "underlyingSource",
      )
      : {};
    this[_brand] = _brand;

    initializeReadableStream(this);
    if (underlyingSourceDict.type === "bytes") {
      if (strategy.size !== undefined) {
        throw new RangeError(
          `${prefix}: When underlying source is "bytes", strategy.size must be 'undefined'`,
        );
      }
      const highWaterMark = extractHighWaterMark(strategy, 0);
      setUpReadableByteStreamControllerFromUnderlyingSource(
        // @ts-ignore cannot easily assert this is ReadableStream<ArrayBuffer>
        this,
        underlyingSource,
        underlyingSourceDict,
        highWaterMark,
      );
    } else {
      const sizeAlgorithm = extractSizeAlgorithm(strategy);
      const highWaterMark = extractHighWaterMark(strategy, 1);
      setUpReadableStreamDefaultControllerFromUnderlyingSource(
        this,
        underlyingSource,
        underlyingSourceDict,

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass only { highWaterMark } for byte streams — drop the size key.
  2. Build strategies conditionally: include size only when the source type is not 'bytes'.
  3. Strip the key before constructing: const { size, ...rest } = strategy; new ReadableStream(src, rest).

Example fix

// before
new ReadableStream(byteSource, { size: (c) => c.byteLength, highWaterMark: 1024 }); // RangeError

// after
new ReadableStream(byteSource, { highWaterMark: 1024 }); // size omitted
Defensive patterns

Strategy: validation

Validate before calling

function byteStreamStrategy(hwm) {
  return { highWaterMark: hwm ?? 0 }; // byte streams must not carry a size fn
}
new ReadableStream({ type: 'bytes', ...source }, byteStreamStrategy(1024));

Prevention

When it happens

Trigger: new ReadableStream({ type: 'bytes', ... }, { size: (c) => c.byteLength, highWaterMark }) — including size functions copied from value-stream code; a shared STRATEGY constant passed to both kinds of streams; a strategy-builder helper that always sets size.

Common situations: Refactoring a value stream into a byte stream while keeping its strategy; shared option objects across a codebase; TypeScript types that suggest size is always allowed.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/21a20b6cdac8327a. Report an issue: GitHub.