{"record":{"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/dce7939f86fb283e167ad709955abedb7bf23124/src/gridfs/download.ts#L195-L231","documentation":"GridFSBucketReadStream.start() and end() mutate read-range options, but only before the stream begins reading. throwIfInitialized (src/gridfs/download.ts:211) checks the internal init flag and throws MongoGridFSStreamError once the stream has entered flowing mode (e.g. after a 'data' listener is attached or _read has run). This prevents inconsistent range state after bytes have been requested.","triggerScenarios":"Calling stream.start(n) or stream.end(n) after attaching a 'data' listener, after piping the stream, or after awaiting any consumption. Calling start()/end() after the stream has emitted its first chunk.","commonSituations":"Attaching on('data') then conditionally calling start() based on metadata received from the 'file' event. Reusing a stream instance and trying to reconfigure it for a second read.","solutions":["Call start() and end() synchronously after openDownloadStream() and before attaching any data listener or piping.","Pass start and end directly in openDownloadStream(id, { start, end }) instead of using the chained setters.","If you need a different range, open a new stream rather than reconfiguring an existing one."],"exampleFix":"// before\nconst s = bucket.openDownloadStream(id);\ns.on('data', chunk => {});\ns.start(100); // throws\n// after\nconst s = bucket.openDownloadStream(id, { start: 100 });\ns.on('data', chunk => {});","handlingStrategy":"validation","validationCode":"function openRangeStream(bucket, id, range) {\n  // pass range at construction; never mutate after\n  return bucket.openDownloadStream(id, range);\n}","typeGuard":"function isUninitialized(stream: GridFSBucketReadStream): boolean {\n  return !(stream as any).s?.init;\n}","tryCatchPattern":"try {\n  stream.start(n);\n} catch (e) {\n  if (e instanceof MongoGridFSStreamError && /cannot be changed after/.test(e.message)) {\n    // open a fresh stream with the desired range\n  }\n  throw e;\n}","preventionTips":["Pass start/end in openDownloadStream options rather than using the chained setters.","Never attach data listeners before configuring the range.","Open a new stream for each distinct range read."],"tags":["gridfs","stream","lifecycle","synchronous"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}