mongodb/node-mongodb-native · error · MongoRuntimeError

File not found for id ${id}

Error message

File not found for id ${id}

What it means

Thrown by GridFSBucket.delete() when no file in the fs.files collection matches the supplied _id (deletedCount === 0). The driver wraps it as a MongoRuntimeError because GridFS lacks a dedicated 'file not found' error type (tracked as NODE-3483). It fires AFTER any orphaned chunks for that files_id are already cleaned up, so the bucket remains consistent. The id is interpolated into the message for diagnostics.

Source

Thrown at src/gridfs/index.ts:187

        serverSelectionTimeoutMS: this.s.db.client.s.options.serverSelectionTimeoutMS
      });
    }

    const { deletedCount } = await this.s._filesCollection.deleteOne(
      { _id: id },
      { timeoutMS: timeoutContext?.remainingTimeMS }
    );

    const remainingTimeMS = timeoutContext?.remainingTimeMS;
    if (remainingTimeMS != null && remainingTimeMS <= 0)
      throw new MongoOperationTimeoutError(`Timed out after ${timeoutMS}ms`);
    // Delete orphaned chunks before returning FileNotFound
    await this.s._chunksCollection.deleteMany({ files_id: id }, { timeoutMS: remainingTimeMS });

    if (deletedCount === 0) {
      // TODO(NODE-3483): Replace with more appropriate error
      // Consider creating new error MongoGridFSFileNotFoundError
      throw new MongoRuntimeError(`File not found for id ${id}`);
    }
  }

  /** Convenience wrapper around find on the files collection */
  find(filter: Filter<GridFSFile> = {}, options: FindOptions = {}): FindCursor<GridFSFile> {
    return this.s._filesCollection.find(filter, options);
  }

  /**
   * Returns a readable stream (GridFSBucketReadStream) for streaming the
   * file with the given name from GridFS. If there are multiple files with
   * the same name, this will stream the most recent file with the given name
   * (as determined by the `uploadDate` field). You can set the `revision`
   * option to change this behavior.
   */
  openDownloadStreamByName(
    filename: string,
    options?: GridFSBucketReadStreamOptionsWithRevision

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Verify the id exists before deleting, e.g. const file = await bucket.find({ _id: id }).next(); if (!file) return; then call bucket.delete(id).
  2. Confirm you are using the same GridFSBucket instance (same db and bucketName) that uploaded the file.
  3. Ensure id is an ObjectId, not a string: new ObjectId(id) when constructing the filter from a stored string.
  4. Wrap the call in try/catch and treat MongoRuntimeError with this message as a benign no-op if idempotent deletion is intended.

Example fix

// before
await bucket.delete(id); // throws if id absent

// after
const existing = await bucket.find({ _id: id }, { limit: 1 }).next();
if (existing) {
  await bucket.delete(id);
}
Defensive patterns

Strategy: validation

Validate before calling

async function safeDelete(bucket, id) {
  const exists = await bucket.find({ _id: id }, { limit: 1 }).hasNext();
  if (!exists) return { deleted: false };
  await bucket.delete(id);
  return { deleted: true };
}

Type guard

import { ObjectId } from 'mongodb';
function isObjectId(v): v is ObjectId {
  return v instanceof ObjectId;
}

Try / catch

try {
  await bucket.delete(id);
} catch (e) {
  if (e instanceof MongoRuntimeError && /File not found/.test(e.message)) return;
  throw e;
}

Prevention

When it happens

Trigger: Calling bucket.delete(id) with an ObjectId that was never uploaded, was already deleted, or belongs to a different bucket (different bucketName / database). Also triggered if the files collection was edited out-of-band or the wrong GridFSBucket instance is used.

Common situations: Deleting a file after it was already deleted; using an id fetched from a different environment/database; race conditions where another process deletes the file first; passing a string id instead of an ObjectId so the filter matches nothing.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/3ea39a78825c6de4.json. Report an issue: GitHub.