mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Option "explain" is not supported on this command
Error message
Option "explain" is not supported on this command
What it means
Thrown by CommandOperation's constructor when the caller passes an explain option to a command operation that does not declare the EXPLAINABLE aspect. Only certain commands (find, aggregate, etc.) can be explained; arbitrary runCommand-style operations reject explain because the server would reject it anyway.
Solutions
- If you need explain output, use a supported public API like collection.find().explain() or collection.aggregate(pipeline, { explain: true }).
- For custom CommandOperation subclasses, declare EXPLAINABLE in the constructor: super(options); and add Aspect.EXPLAINABLE via getAspectName / aspects.
- Drop the explain option if you do not actually need it for this command.
Example fix
// before (custom op)
class MyOp extends CommandOperation {
constructor(parent, options) { super(parent, { ...options, explain: true }); }
}
// after
class MyOp extends CommandOperation {
constructor(parent, options) {
super(parent, options);
this.explain = Explain.fromOptions(options);
}
override get commandName() { return 'myCmd' as const; }
// declare EXPLAINABLE aspect where the operation is registered
buildCommandDocument() { /* ... */ }
} Defensive patterns
Strategy: validation
Validate before calling
if (options?.explain != null && !operation.hasAspect?.(EXPLAINABLE)) {
delete options.explain;
// or throw: 'explain not supported here'
} Prevention
- Prefer the public .explain() method on cursors instead of passing explain through options.
- When subclassing CommandOperation, declare Aspect.EXPLAINABLE explicitly.
When it happens
Trigger: Calling an internal command operation with { explain: true } in its options when the operation class has not declared Aspect.EXPLAINABLE. Public API misuse via Db.command(..., { explain }) or custom Operation subclasses.
Common situations: Subclassing CommandOperation for a custom command and forgetting to add Aspect.EXPLAINABLE to the aspects array; passing through generic option maps that include explain by accident.
Related errors
- This method requires a valid operation instance
- Argument "docs" must be an array of documents
- Argument "operations" must be an array of documents
- Argument "pipeline" must be an array of aggregation stages
- Cannot use maxTimeMS with timeoutMS for explain commands.
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/62051f66ac0921cb.
Report an issue: GitHub.
Appendix: source
Thrown at src/operations/command.ts:104
// something we'd want to reconsider. Perhaps those commands can use `Admin`
// as a parent?
const dbNameOverride = options?.dbName || options?.authdb;
if (dbNameOverride) {
this.ns = new MongoDBNamespace(dbNameOverride, '$cmd');
} else {
this.ns = parent
? parent.s.namespace.withCollection('$cmd')
: new MongoDBNamespace('admin', '$cmd');
}
this.readConcern = ReadConcern.fromOptions(options);
this.writeConcern = WriteConcern.fromOptions(options);
if (this.hasAspect(Aspect.EXPLAINABLE)) {
this.explain = Explain.fromOptions(options);
if (this.explain) validateExplainTimeoutOptions(this.options, this.explain);
} else if (options?.explain != null) {
throw new MongoInvalidArgumentError(`Option "explain" is not supported on this command`);
}
}
override get canRetryWrite(): boolean {
if (this.hasAspect(Aspect.EXPLAINABLE)) {
return this.explain == null;
}
return super.canRetryWrite;
}
abstract buildCommandDocument(connection: Connection, session?: ClientSession): Document;
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
return {
...this.options,
...this.bsonOptions,
timeoutContext,
readPreference: this.readPreference,View on GitHub (pinned to dce7939f86)