{"id":"3da03eb7500056ec","repo":"mongodb/node-mongodb-native","slug":"timed-out-after-timeoutms-ms","errorCode":null,"errorMessage":"Timed out after ${timeoutMS}ms","messagePattern":"Timed out after (.+?)ms","errorType":"exception","errorClass":"MongoOperationTimeoutError","httpStatus":null,"severity":"error","filePath":"src/gridfs/index.ts","lineNumber":180,"sourceCode":"  async delete(id: ObjectId, options?: { timeoutMS: number }): Promise<void> {\n    const { timeoutMS } = resolveOptions(this.s.db, options);\n    let timeoutContext: CSOTTimeoutContext | undefined = undefined;\n\n    if (timeoutMS) {\n      timeoutContext = new CSOTTimeoutContext({\n        timeoutMS,\n        serverSelectionTimeoutMS: this.s.db.client.s.options.serverSelectionTimeoutMS\n      });\n    }\n\n    const { deletedCount } = await this.s._filesCollection.deleteOne(\n      { _id: id },\n      { timeoutMS: timeoutContext?.remainingTimeMS }\n    );\n\n    const remainingTimeMS = timeoutContext?.remainingTimeMS;\n    if (remainingTimeMS != null && remainingTimeMS <= 0)\n      throw new MongoOperationTimeoutError(`Timed out after ${timeoutMS}ms`);\n    // Delete orphaned chunks before returning FileNotFound\n    await this.s._chunksCollection.deleteMany({ files_id: id }, { timeoutMS: remainingTimeMS });\n\n    if (deletedCount === 0) {\n      // TODO(NODE-3483): Replace with more appropriate error\n      // Consider creating new error MongoGridFSFileNotFoundError\n      throw new MongoRuntimeError(`File not found for id ${id}`);\n    }\n  }\n\n  /** Convenience wrapper around find on the files collection */\n  find(filter: Filter<GridFSFile> = {}, options: FindOptions = {}): FindCursor<GridFSFile> {\n    return this.s._filesCollection.find(filter, options);\n  }\n\n  /**\n   * Returns a readable stream (GridFSBucketReadStream) for streaming the\n   * file with the given name from GridFS. If there are multiple files with","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/gridfs/index.ts#L162-L198","documentation":"A MongoOperationTimeoutError raised by GridFSBucket.delete() when the cumulative time spent (after deleting the files doc) leaves no budget for the orphaned-chunks cleanup, per CSOT semantics. The message reports the original timeoutMS that was requested.","triggerScenarios":"await bucket.delete(id, { timeoutMS: 50 }) where deleteOne + deleteMany cannot both finish in time, or the remaining budget hits zero between the two steps.","commonSituations":"Aggressive timeoutMS on large files; slow or overloaded server; missing index on chunks.files_id; high-latency network.","solutions":["Increase timeoutMS for deletes of large GridFS files","Drop timeoutMS for this op if CSOT isn't strictly required","Ensure an index exists on chunks.files_id so deleteMany is fast","Move large deletes off peak load"],"exampleFix":"// before\nawait bucket.delete(id, { timeoutMS: 100 });\n// after\nawait bucket.delete(id, { timeoutMS: 5000 });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await bucket.delete(id, { timeoutMS });\n} catch (err) {\n  if (err instanceof MongoOperationTimeoutError) {\n    await bucket.delete(id, { timeoutMS: timeoutMS * 4 }); // retry idempotent delete with larger budget\n  } else throw err;\n}","preventionTips":["Size timeoutMS to file size and chunk count","Ensure the chunks collection is indexed on files_id","Retry idempotent deletes with a larger budget","Move large GridFS deletes off peak load"],"tags":["gridfs","timeout","csot"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}