mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Stream end ( ) must not be negative

Error message

Stream end (${options.end}) must not be negative

What it means

handleEndOption (src/gridfs/download.ts:470) throws MongoInvalidArgumentError when end is provided but start is null or negative. The message text says 'must not be negative' but the actual guard rejects a missing/invalid start in conjunction with an end value, because a valid range requires a valid start.

Solutions

  1. Always provide a non-negative start when supplying end: openDownloadStream(id, { start: 0, end: N }).
  2. Validate that start is a non-negative integer whenever end is set.

Example fix

// before
const s = bucket.openDownloadStream(id, { end: 1000 });
// after
const s = bucket.openDownloadStream(id, { start: 0, end: 1000 });
Defensive patterns

Strategy: validation

Validate before calling

function normalizeEndRange(range) {
  if (range?.end != null) {
    range.start = Math.max(0, range.start ?? 0);
  }
  return range;
}

Type guard

function hasValidStartForEnd(range: any): boolean {
  return range?.end == null || (typeof range.start === 'number' && range.start >= 0);
}

Try / catch

try {
  bucket.openDownloadStream(id, { end });
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /must not be negative/.test(e.message)) {
    // add start: 0
  }
}

Prevention

When it happens

Trigger: Calling openDownloadStream(id, { end: N }) with no start, or with start < 0. Internally, handleEndOption requires options.start to be a non-negative number when end is set.

Common situations: Passing only an end offset assuming start defaults to 0 internally (it does not in this code path). Mixing negative start with a positive end.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/4f5a099821f04592. Report an issue: GitHub.

Appendix: source

Thrown at src/gridfs/download.ts:471

    return options.start - stream.s.bytesRead;
  }
  throw new MongoInvalidArgumentError('Start option must be defined');
}

function handleEndOption(
  stream: GridFSBucketReadStream,
  doc: Document,
  cursor: FindCursor<GridFSChunk>,
  options: GridFSBucketReadStreamOptions
) {
  if (options && options.end != null) {
    if (options.end > doc.length) {
      throw new MongoInvalidArgumentError(
        `Stream end (${options.end}) must not be more than the length of the file (${doc.length})`
      );
    }
    if (options.start == null || options.start < 0) {
      throw new MongoInvalidArgumentError(`Stream end (${options.end}) must not be negative`);
    }

    const start = options.start != null ? Math.floor(options.start / doc.chunkSize) : 0;

    cursor.limit(Math.ceil(options.end / doc.chunkSize) - start);

    stream.s.expectedEnd = Math.ceil(options.end / doc.chunkSize);

    return Math.ceil(options.end / doc.chunkSize) * doc.chunkSize - options.end;
  }
  throw new MongoInvalidArgumentError('End option must be defined');
}

View on GitHub (pinned to dce7939f86)