{"id":"7c675547c72b1a82","repo":"mongodb/node-mongodb-native","slug":"options-cannot-be-changed-after-the-stream-is-init","errorCode":null,"errorMessage":"Options cannot be changed after the stream is initialized","messagePattern":"Options cannot be changed after the stream is initialized","errorType":"exception","errorClass":"MongoGridFSStreamError","httpStatus":null,"severity":"error","filePath":"src/gridfs/download.ts","lineNumber":213,"sourceCode":"    return this;\n  }\n\n  /**\n   * Marks this stream as aborted (will never push another `data` event)\n   * and kills the underlying cursor. Will emit the 'end' event, and then\n   * the 'close' event once the cursor is successfully killed.\n   */\n  async abort(): Promise<void> {\n    this.push(null);\n    this.destroy();\n    const remainingTimeMS = this.s.timeoutContext?.getRemainingTimeMSOrThrow();\n    await this.s.cursor?.close({ timeoutMS: remainingTimeMS });\n  }\n}\n\nfunction throwIfInitialized(stream: GridFSBucketReadStream): void {\n  if (stream.s.init) {\n    throw new MongoGridFSStreamError('Options cannot be changed after the stream is initialized');\n  }\n}\n\nfunction doRead(stream: GridFSBucketReadStream): void {\n  if (stream.destroyed) return;\n  if (!stream.s.cursor) return;\n  if (!stream.s.file) return;\n\n  const handleReadResult = (doc: Document | null) => {\n    if (stream.destroyed) return;\n\n    if (!doc) {\n      stream.push(null);\n\n      stream.s.cursor?.close().then(undefined, error => stream.destroy(error));\n      return;\n    }\n","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/gridfs/download.ts#L195-L231","documentation":"GridFSBucketReadStream.start()/end() set byte-range options but only before the stream has initialized (fetched the file document). Once init is true (after the first _read or a 'file' event), the range math is fixed and late mutations are rejected to avoid corrupting bytesToSkip/bytesToTrim.","triggerScenarios":"Calling .start(100) or .end(500) after attaching a 'data' listener, calling .read(), or emitting the 'file' event.","commonSituations":"Lazy range configuration inside event handlers; reusing a stream after partial consumption; chaining .start() after pipe().","solutions":["Pass start/end in the openDownloadStream options at construction time","Call .start()/.end() before attaching any 'data' listener or calling read()","Open a brand-new stream if the range needs to change mid-flight"],"exampleFix":"// before\nconst s = bucket.openDownloadStream(id);\ns.on('data', cb);\ns.start(100); // throws\n// after\nconst s = bucket.openDownloadStream(id, { start: 100 });\ns.on('data', cb);","handlingStrategy":"validation","validationCode":"function openRange(bucket, id, start, end) {\n  // always configure range at construction\n  return bucket.openDownloadStream(id, { start, end });\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure the byte range in openDownloadStream options","Never call .start()/.end() after attaching 'data' listeners","Open a new stream when the range must change"],"tags":["gridfs","stream","api-misuse"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}