denoland/deno · error · RangeError
"bytesWritten" out of range
Error message
"bytesWritten" out of range
What it means
RangeError from ReadableStreamBYOBRequest.respond(bytesWritten): firstDescriptor.bytesFilled + bytesWritten exceeds firstDescriptor.byteLength, meaning you reported more bytes than fit in the capacity handed out in byobRequest.view. The descriptor tracks how much of the consumer's view is already filled; over-reporting would claim memory beyond the view.
Source
Thrown at ext/web/06_streams.js:2609
if (state === "closed") {
if (bytesWritten !== 0) {
throw new TypeError(
`"bytesWritten" must be 0 when calling respond() on a closed stream: received ${bytesWritten}`,
);
}
} else {
assert(state === "readable");
if (bytesWritten === 0) {
throw new TypeError(
'"bytesWritten" must be greater than 0 when calling respond() on a readable stream',
);
}
if (
(firstDescriptor.bytesFilled + bytesWritten) >
// deno-lint-ignore deno-internal/prefer-primordials
firstDescriptor.byteLength
) {
throw new RangeError('"bytesWritten" out of range');
}
}
firstDescriptor.buffer = ArrayBufferPrototypeTransferToFixedLength(
// deno-lint-ignore deno-internal/prefer-primordials
firstDescriptor.buffer,
);
readableByteStreamControllerRespondInternal(controller, bytesWritten);
}
/**
* @param {ReadableByteStreamController} controller
* @param {number} bytesWritten
* @param {PullIntoDescriptor} pullIntoDescriptor
* @returns {void}
*/
function readableByteStreamControllerRespondInReadableState(
controller,
bytesWritten,View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Respond with this read call's count only: byob.respond(bytesReadThisCall).
- Clamp before responding: bytesWritten = Math.min(bytesWritten, byob.view.byteLength).
- When coalescing partial writes, keep a local fill counter and respond with only what fits; leave the rest for the next pull().
Example fix
// before
let total = 0;
for (const part of parts) { total += part.length; copyInto(byob.view, part); }
byob.respond(total); // exceeds view capacity -> RangeError
// after
let filled = 0;
for (const part of parts) {
if (filled + part.length > byob.view.byteLength) break;
copyInto(byob.view.subarray(filled), part);
filled += part.length;
}
byob.respond(filled); Defensive patterns
Strategy: validation
Validate before calling
const cap = byob.view.byteLength; // capacity handed out const n = Math.min(bytesWritten, cap); // never over-report if (n > 0) byob.respond(n); else controller.close();
Try / catch
try {
byob.respond(n);
} catch (e) {
if (e instanceof RangeError && e.message.includes('out of range')) {
byob.respond(byob.view.byteLength); // retry with the valid maximum
return;
}
throw e;
} Prevention
- respond() takes this operation's byte count, never an accumulator.
- Keep a local fill counter when coalescing partial writes.
- Assert n <= byob.view.byteLength in development builds.
When it happens
Trigger: Passing bytesWritten greater than byobRequest.view.byteLength; summing bytes across several partial reads into one respond(); confusing units (bits vs bytes, total file offset vs chunk length); ignoring that an earlier partial fill already consumed part of the view.
Common situations: Read loops that accumulate totals and respond once; porting Node 'bytesWritten' semantics; responding with a payload length plus header size that exceeds the view.
Related errors
- The region specified by view is larger than byobRequest
- "bytesWritten" must be 0 when calling respond() on a closed
- "bytesWritten" must be greater than 0 when calling respond()
- The region specified by view does not match byobRequest
- The buffer of view has different capacity than byobRequest
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/acc179588bf6c2b4.
Report an issue: GitHub.