{"record":{"id":"534b85066b102324","repo":"mongodb/node-mongodb-native","slug":"stream-start-options-start-must-not-be-negati","errorCode":null,"errorMessage":"Stream start (${options.start}) must not be negative","messagePattern":"Stream start \\((.+?)\\) must not be negative","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/gridfs/download.ts","lineNumber":442,"sourceCode":"\n  stream.once('file', () => {\n    callback();\n  });\n}\n\nfunction handleStartOption(\n  stream: GridFSBucketReadStream,\n  doc: Document,\n  options: GridFSBucketReadStreamOptions\n): number {\n  if (options && options.start != null) {\n    if (options.start > doc.length) {\n      throw new MongoInvalidArgumentError(\n        `Stream start (${options.start}) must not be more than the length of the file (${doc.length})`\n      );\n    }\n    if (options.start < 0) {\n      throw new MongoInvalidArgumentError(`Stream start (${options.start}) must not be negative`);\n    }\n    if (options.end != null && options.end < options.start) {\n      throw new MongoInvalidArgumentError(\n        `Stream start (${options.start}) must not be greater than stream end (${options.end})`\n      );\n    }\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,","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/gridfs/download.ts#L424-L460","documentation":"handleStartOption (src/gridfs/download.ts:441) rejects negative start offsets with MongoInvalidArgumentError. The start parameter is a 0-based byte offset, so negative values are meaningless and indicate a caller bug.","triggerScenarios":"Calling openDownloadStream(id, { start: -1 }) or stream.start(-10). Passing a computed offset that underflows to a negative number (e.g. subtracting too aggressively).","commonSituations":"Arithmetic on offsets producing negatives when the file is smaller than a chunk size assumption. Off-by-one errors in resume logic.","solutions":["Ensure start is a non-negative integer; clamp with Math.max(0, value).","Validate the input at the application boundary and reject/normalize negative offsets before calling openDownloadStream."],"exampleFix":"// before\nconst s = bucket.openDownloadStream(id, { start: offset - 50 });\n// after\nconst s = bucket.openDownloadStream(id, { start: Math.max(0, offset - 50) });","handlingStrategy":"validation","validationCode":"function clampStart(start) {\n  return Math.max(0, Math.floor(start));\n}\nconst s = bucket.openDownloadStream(id, { start: clampStart(userStart) });","typeGuard":"function isNonNegativeInt(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 0;\n}","tryCatchPattern":"try {\n  bucket.openDownloadStream(id, { start });\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /must not be negative/.test(e.message)) {\n    start = 0;\n  }\n}","preventionTips":["Clamp offset arithmetic with Math.max(0, value).","Validate range inputs at the API boundary.","Add tests around offset edge cases (zero, below zero)."],"tags":["gridfs","stream","validation","range"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}