mongodb/node-mongodb-native · error · MongoAPIError
Cannot use maxTimeMS with timeoutMS for explain commands.
Error message
Cannot use maxTimeMS with timeoutMS for explain commands.
What it means
Under Client-Side Operation Timeout (CSOT, the timeoutMS option) combining maxTimeMS with timeoutMS on explain commands is ambiguous and explicitly forbidden by validateExplainTimeoutOptions(). Pick a single timeout mechanism for explain.
Source
Thrown at src/explain.ts:96
this.maxTimeMS = maxTimeMS;
}
static fromOptions({ explain }: ExplainOptions = {}): Explain | undefined {
if (explain == null) return;
if (typeof explain === 'boolean' || typeof explain === 'string') {
return new Explain(explain);
}
const { verbosity, maxTimeMS } = explain;
return new Explain(verbosity, maxTimeMS);
}
}
export function validateExplainTimeoutOptions(options: Document, explain?: Explain) {
const { maxTimeMS, timeoutMS } = options;
if (timeoutMS != null && (maxTimeMS != null || explain?.maxTimeMS != null)) {
throw new MongoAPIError('Cannot use maxTimeMS with timeoutMS for explain commands.');
}
}
/**
* Applies an explain to a given command.
* @internal
*
* @param command - the command on which to apply the explain
* @param options - the options containing the explain verbosity
*/
export function decorateWithExplain(
command: Document,
explain: Explain
): {
explain: Document;
verbosity: ExplainVerbosity;
maxTimeMS?: number;
} {View on GitHub (pinned to 3366c21a63)
Solutions
- Remove maxTimeMS from the explain options and rely on timeoutMS alone
- Or remove timeoutMS for this operation and keep maxTimeMS
- Standardize the project on timeoutMS and audit for leftover maxTimeMS
Example fix
// before
collection.find(f, { explain: { verbosity: 'queryPlanner', maxTimeMS: 1000 }, timeoutMS: 5000 });
// after
collection.find(f, { explain: { verbosity: 'queryPlanner' }, timeoutMS: 5000 }); Defensive patterns
Strategy: validation
Validate before calling
function assertExplainTimeout(options) {
const hasMaxTime = options?.explain && typeof options.explain === 'object'
&& options.explain.maxTimeMS != null;
if (options?.timeoutMS != null && (options?.maxTimeMS != null || hasMaxTime)) {
throw new Error('Pick either maxTimeMS or timeoutMS for explain, not both');
}
} Prevention
- Adopt timeoutMS project-wide and remove legacy maxTimeMS
- Never mix the two on explain-bearing operations
- Lint options objects for the conflict
When it happens
Trigger: collection.find(filter, { explain: { verbosity: 'queryPlanner', maxTimeMS: 1000 }, timeoutMS: 5000 }), or setting maxTimeMS on the command while timeoutMS is configured on the client/cursor.
Common situations: Migrating to CSOT while leaving legacy maxTimeMS in place; copy-pasting explain options into a timeoutMS-enabled codebase.
Related errors
- KMS request timed out
- Server roundtrip time is greater than the time remaining
- Server reported a timeout error
- Timed out during connection checkout
- Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable aw
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/da85d8bb7f9692a5.json.
Report an issue: GitHub.