{"id":"93e2479a5c42bf62","repo":"mongodb/node-mongodb-native","slug":"stream-end-options-end-must-not-be-more-than","errorCode":null,"errorMessage":"Stream end (${options.end}) must not be more than the length of the file (${doc.length})","messagePattern":"Stream end \\((.+?)\\) must not be more than the length of the file \\((.+?)\\)","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/gridfs/download.ts","lineNumber":466,"sourceCode":"    }\n\n    stream.s.bytesRead = Math.floor(options.start / doc.chunkSize) * doc.chunkSize;\n    stream.s.expected = Math.floor(options.start / doc.chunkSize);\n\n    return options.start - stream.s.bytesRead;\n  }\n  throw new MongoInvalidArgumentError('Start option must be defined');\n}\n\nfunction handleEndOption(\n  stream: GridFSBucketReadStream,\n  doc: Document,\n  cursor: FindCursor<GridFSChunk>,\n  options: GridFSBucketReadStreamOptions\n) {\n  if (options && options.end != null) {\n    if (options.end > doc.length) {\n      throw new MongoInvalidArgumentError(\n        `Stream end (${options.end}) must not be more than the length of the file (${doc.length})`\n      );\n    }\n    if (options.start == null || options.start < 0) {\n      throw new MongoInvalidArgumentError(`Stream end (${options.end}) must not be negative`);\n    }\n\n    const start = options.start != null ? Math.floor(options.start / doc.chunkSize) : 0;\n\n    cursor.limit(Math.ceil(options.end / doc.chunkSize) - start);\n\n    stream.s.expectedEnd = Math.ceil(options.end / doc.chunkSize);\n\n    return Math.ceil(options.end / doc.chunkSize) * doc.chunkSize - options.end;\n  }\n  throw new MongoInvalidArgumentError('End option must be defined');\n}\n","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/gridfs/download.ts#L448-L484","documentation":"handleEndOption validates that the requested end offset does not exceed the file's length. An end past EOF is rejected to keep the byte math consistent.","triggerScenarios":"bucket.openDownloadStream(id, { end: file.length + 50 }) when the file is shorter than expected.","commonSituations":"Off-by-one; stale length assumption; using end as an exclusive bound against a truncated file.","solutions":["Clamp end with Math.min(end, file.length) using the file document's length","Look up the file length before opening the stream","Validate user-supplied ranges against the actual file size"],"exampleFix":"// before\n{ end: requestedEnd }\n// after\n{ end: Math.min(requestedEnd, file.length) }","handlingStrategy":"validation","validationCode":"async function clampEnd(bucket, id, desired) {\n  const file = await bucket.find({ _id: id }).next();\n  return Math.min(desired, file?.length ?? 0);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Look up the file length before computing end","Clamp end with Math.min(end, file.length)"],"tags":["gridfs","stream","validation"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}