{"record":{"id":"93741a3f0bd95fcc","repo":"denoland/deno","slug":"byteswritten-must-be-greater-than-0-when-calling","errorCode":null,"errorMessage":"\"bytesWritten\" must be greater than 0 when calling respond() on a readable stream","messagePattern":"\"bytesWritten\" must be greater than 0 when calling respond\\(\\) on a readable stream","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/web/06_streams.js","lineNumber":2600,"sourceCode":"/**\n * @param {ReadableByteStreamController} controller\n * @param {number} bytesWritten\n * @returns {void}\n */\nfunction readableByteStreamControllerRespond(controller, bytesWritten) {\n  assert(controller[_pendingPullIntos].size !== 0);\n  const firstDescriptor = controller[_pendingPullIntos].peek();\n  const state = controller[_stream][_state];\n  if (state === \"closed\") {\n    if (bytesWritten !== 0) {\n      throw new TypeError(\n        `\"bytesWritten\" must be 0 when calling respond() on a closed stream: received ${bytesWritten}`,\n      );\n    }\n  } else {\n    assert(state === \"readable\");\n    if (bytesWritten === 0) {\n      throw new TypeError(\n        '\"bytesWritten\" must be greater than 0 when calling respond() on a readable stream',\n      );\n    }\n    if (\n      (firstDescriptor.bytesFilled + bytesWritten) >\n        // deno-lint-ignore deno-internal/prefer-primordials\n        firstDescriptor.byteLength\n    ) {\n      throw new RangeError('\"bytesWritten\" out of range');\n    }\n  }\n  firstDescriptor.buffer = ArrayBufferPrototypeTransferToFixedLength(\n    // deno-lint-ignore deno-internal/prefer-primordials\n    firstDescriptor.buffer,\n  );\n  readableByteStreamControllerRespondInternal(controller, bytesWritten);\n}\n","sourceCodeStart":2582,"sourceCodeEnd":2618,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/06_streams.js#L2582-L2618","documentation":"ReadableStreamBYOBRequest.respond() was called with bytesWritten = 0 while the stream is still 'readable'. A zero-byte respond cannot satisfy the pending BYOB read, so the spec requires at least one byte; 'no bytes available' must instead be expressed by closing the stream (or by returning a pending promise from pull()).","triggerScenarios":"An OS read into byobRequest.view returns 0 bytes (EOF) and the adapter calls byob.respond(0) instead of controller.close(); an error path that 'responds with nothing' rather than calling controller.error(err).","commonSituations":"Adapting POSIX read()/file descriptors or sockets to a type: 'bytes' stream; TCP reads returning 0 on peer disconnect; loops copied from default-reader code where signaling emptiness is legal.","solutions":["Treat bytesRead === 0 as EOF: call controller.close() and return without responding.","If the operation failed, call controller.error(err) instead of respond(0).","Only call respond(n) after actually writing n >= 1 bytes into byobRequest.view."],"exampleFix":"// before\nconst { bytesRead } = await read(fd, byob.view);\nbyob.respond(bytesRead); // bytesRead === 0 -> TypeError: must be greater than 0\n\n// after\nconst { bytesRead } = await read(fd, byob.view);\nif (bytesRead === 0) { controller.close(); return; } // EOF\nbyob.respond(bytesRead);","handlingStrategy":"validation","validationCode":"if (bytesRead === 0) { controller.close(); return; } // EOF, not respond(0)\nif (controller.byobRequest !== null) controller.byobRequest.respond(bytesRead);","typeGuard":null,"tryCatchPattern":"try {\n  byob.respond(n);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('must be greater than 0')) {\n    controller.close(); // zero bytes on a readable stream means EOF\n    return;\n  }\n  throw e;\n}","preventionTips":["Map every zero-byte read to close() and every failed read to controller.error().","Never use respond(0) as a 'nothing happened' signal — return a pending promise from pull() instead."],"tags":["readable-stream","byob-reader","respond","eof","zero-bytes"],"backgroundTag":"byob-request-respond-misuse","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T04:17:50.494Z"}