denoland/deno · error · RangeError

Cannot enqueue value with size: chunk size must be a positiv

Error message

Cannot enqueue value with size: chunk size must be a positive number

What it means

enqueueValueWithSize implements the streams-spec enqueue step: whatever the strategy's size() returns must be a number that is not NaN and not negative (isNonNegativeNumber, ext/web/06_streams.js:702-706), otherwise RangeError 'Cannot enqueue value with size: chunk size must be a positive number'. It runs for every controller.enqueue()/writer.write() on a stream with a custom size function. Despite the wording, 0 is allowed — only NaN and negative values throw here.

Source

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

  assert(container[_queue].size);
  const node = container[_queue].dequeueNode();
  container[_queueTotalSize] -= node.size;
  if (container[_queueTotalSize] < 0) {
    container[_queueTotalSize] = 0;
  }
  return node.value;
}
/**
 * @template T
 * @param {{ [_queue]: Array<ValueWithSize<T | _close>>, [_queueTotalSize]: number }} container
 * @param {T} value
 * @param {number} size
 * @returns {void}
 */
function enqueueValueWithSize(container, value, size) {
  assert(container[_queue] && typeof container[_queueTotalSize] === "number");
  if (isNonNegativeNumber(size) === false) {
    throw new RangeError(
      "Cannot enqueue value with size: chunk size must be a positive number",
    );
  }
  if (size === Infinity) {
    throw new RangeError(
      "Cannot enqueue value with size: chunk size is invalid",
    );
  }
  container[_queue].enqueueWithSize(value, size);
  container[_queueTotalSize] += size;
}

/**
 * @param {QueuingStrategy} strategy
 * @param {number} defaultHWM
 */
function extractHighWaterMark(strategy, defaultHWM) {
  if (strategy.highWaterMark === undefined) {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Make size() total: return c.byteLength when it is a number, otherwise 1 — `(typeof c.byteLength === 'number' ? c.byteLength : 1)`.
  2. Clamp custom sizes: Math.max(0, computed).
  3. Unit-test the size function against every chunk shape the stream actually carries.
  4. Remember 0 is legal; NaN and negatives are not.

Example fix

// before
new ReadableStream(src, { size: (c) => c.byteLength }); // string chunk -> undefined -> throw

// after
new ReadableStream(src, {
  size: (c) => (typeof c.byteLength === 'number' ? c.byteLength : 1),
});
Defensive patterns

Strategy: validation

Validate before calling

const size = (c) => {
  const n = typeof c.byteLength === 'number' ? c.byteLength : 1;
  return Number.isFinite(n) && n >= 0 ? n : 1;
};
new WritableStream(sink, { highWaterMark: 4, size });

Type guard

const isValidChunkSize = (n) =>
  typeof n === 'number' && !Number.isNaN(n) && n >= 0 && n !== Infinity;

Try / catch

try {
  controller.enqueue(chunk);
} catch (e) {
  if (e instanceof RangeError && e.message.includes('chunk size')) {
    fixSizeFunction();
  } else throw e;
}

Prevention

When it happens

Trigger: new ReadableStream(src, { size: (c) => c.byteLength }) with string chunks (c.byteLength is undefined -> not a non-negative number); size: () => -1 from an arithmetic bug; size returning NaN from missing fields.

Common situations: Size functions written for byte chunks reused on object/string streams; size computed from ratios where operands can be missing; refactors that change chunk shape without updating the strategy.

Related errors


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