mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Stream start ( ) must not be more than the length of the…

Error message

Stream start (${options.start}) must not be more than the length of the file (${doc.length})

What it means

When opening a GridFS download stream with a start offset, handleStartOption (src/gridfs/download.ts:435) validates the value against the file's actual length. If start exceeds doc.length, it throws MongoInvalidArgumentError. This fires during stream initialization once the file document has been fetched.

Solutions

  1. Fetch the file metadata first (bucket.find({ _id: id })) and confirm start <= file.length before opening the stream.
  2. Clamp start to the file length, or to 0, if a partial read beyond the end should be treated as empty.
  3. Validate user-provided range inputs against the known file size before passing them to openDownloadStream.

Example fix

// before
const s = bucket.openDownloadStream(id, { start: 100000 });
// after
const file = await bucket.find({ _id: id }).next();
const s = bucket.openDownloadStream(id, { start: Math.min(100000, file.length) });
Defensive patterns

Strategy: validation

Validate before calling

async function safeOpen(bucket, id, range) {
  const file = await bucket.find({ _id: id }).next();
  if (!file) throw new Error('file not found');
  if (range?.start != null && range.start > file.length) {
    range.start = file.length;
  }
  return bucket.openDownloadStream(id, range);
}

Type guard

function isStartWithinLength(start: number, length: number): boolean {
  return Number.isInteger(start) && start >= 0 && start <= length;
}

Try / catch

try {
  return bucket.openDownloadStream(id, { start });
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /must not be more than the length/.test(e.message)) {
    // fetch length and clamp start
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling openDownloadStream(id, { start: N }) where N is greater than the stored file's length. Using a hardcoded offset that is valid for larger files but not for a shorter one being read.

Common situations: Assuming a file is larger than it is (e.g. resuming a download with a stale byte offset after the file was replaced). Computing start from an unverified external source without checking file size.

Related errors


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

Appendix: source

Thrown at src/gridfs/download.ts:437

  if (!stream.s.init) {
    init(stream);
    stream.s.init = true;
  }

  stream.once('file', () => {
    callback();
  });
}

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

    stream.s.bytesRead = Math.floor(options.start / doc.chunkSize) * doc.chunkSize;
    stream.s.expected = Math.floor(options.start / doc.chunkSize);

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

View on GitHub (pinned to dce7939f86)