mongodb/node-mongodb-native · error · MongoRuntimeError
File not found for id
Error message
File not found for id ${id} What it means
GridFSBucket.delete (src/gridfs/index.ts:184) throws MongoRuntimeError 'File not found for id' when the deleteOne on the files collection matched zero documents. The driver deletes orphaned chunks first, then reports the missing file. The id type is ObjectId; a mismatched or non-existent id triggers this.
Solutions
- Check existence before deleting: const file = await bucket.find({ _id: id }).next(); if (file) await bucket.delete(id).
- Make delete idempotent by catching the error and treating 'not found' as success when appropriate.
- Verify the id is an ObjectId and that the bucket name/namespace matches where the file was uploaded.
Example fix
// before
await bucket.delete(id); // throws if missing
// after
const file = await bucket.find({ _id: id }).next();
if (file) await bucket.delete(id); Defensive patterns
Strategy: try-catch
Validate before calling
async function deleteIfExists(bucket, id) {
const file = await bucket.find({ _id: id }).next();
if (!file) return false;
await bucket.delete(id);
return true;
} Type guard
function isObjectId(v: unknown): v is ObjectId {
return v != null && typeof v === 'object' && '_bsontype' in v && (v as any)._bsontype === 'ObjectId';
} Try / catch
try {
await bucket.delete(id);
} catch (e) {
if (e instanceof MongoRuntimeError && /File not found/.test(e.message)) {
// treat as idempotent success
} else throw e;
} Prevention
- Make delete operations idempotent by tolerating 'not found'.
- Verify the id is the ObjectId returned by the upload stream.
- Confirm the bucketName matches between upload and delete.
When it happens
Trigger: Calling bucket.delete(id) for an id that was never uploaded or was already deleted. Passing a string id where an ObjectId is expected, or an ObjectId from a different bucket/database.
Common situations: Retry/idempotency logic calling delete twice. Stale id cached from a previous session. Using the wrong bucket instance (custom bucketName) so the files collection differs.
Related errors
- File with id not found
- End option must be defined
- Start option must be defined
- Stream end ( ) must not be more than the length of the file…
- Stream end ( ) must not be negative
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/3ea39a78825c6de4.
Report an issue: GitHub.
Appendix: 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?: GridFSBucketReadStreamOptionsWithRevisionView on GitHub (pinned to dce7939f86)