{"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/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/gridfs/download.ts#L424-L460","documentation":"handleStartOption rejects negative start offsets because byte offsets are 0-indexed and non-negative. This guards against off-by-one pagination math and unvalidated user input.","triggerScenarios":"bucket.openDownloadStream(id, { start: -1 }) or any path producing a negative start.","commonSituations":"Pagination math like offset - 1 with offset 0; unvalidated query params; swapped subtraction order.","solutions":["Clamp start with Math.max(0, n) before opening the stream","Validate user-provided offsets are non-negative integers"],"exampleFix":"// before\n{ start: offset - 1 } // offset 0 yields -1\n// after\n{ start: Math.max(0, offset - 1) }","handlingStrategy":"validation","validationCode":"const safeStart = Math.max(0, Number(userStart) || 0);","typeGuard":"function isNonNegativeInt(n: unknown): n is number {\n  return typeof n === 'number' && Number.isInteger(n) && n >= 0;\n}","tryCatchPattern":null,"preventionTips":["Clamp offsets with Math.max(0, n)","Validate pagination inputs are non-negative integers"],"tags":["gridfs","stream","validation"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}