mongodb/node-mongodb-native · error · MongoAPIError

RunCommandCursor does not support readConcern it must be…

Error message

RunCommandCursor does not support readConcern it must be attached to the command being run

What it means

Thrown by RunCommandCursor.withReadConcern because the cursor cannot inject readConcern into the command post-hoc. The command document passed to db.runCursorCommand is frozen and sent verbatim, so any readConcern must already be present on that document. This override exists to prevent a silent no-op where withReadConcern would appear to succeed but the server would ignore it.

Solutions

  1. Put readConcern directly on the command: db.runCursorCommand({ find: 'coll', filter: {}, readConcern: { level: 'majority' } }).
  2. Drop the withReadConcern call on RunCommandCursor.
  3. Branch generic cursor middleware to skip withReadConcern when the cursor is a RunCommandCursor.

Example fix

// before
cursor.withReadConcern('majority');

// after
db.runCursorCommand({
  aggregate: 'coll',
  pipeline: [],
  cursor: {},
  readConcern: { level: 'majority' }
});
Defensive patterns

Strategy: validation

Validate before calling

function buildCommandWithReadConcern(cmd, level) {
  return { ...cmd, readConcern: { level } };
}
// usage: db.runCursorCommand(buildCommandWithReadConcern(cmd, 'majority'))

Type guard

function isRunCommandCursor(cursor) { return cursor instanceof RunCommandCursor; }

Prevention

When it happens

Trigger: Calling cursor.withReadConcern('majority') on a RunCommandCursor; generic middleware that applies readConcern to every cursor; attempting to set a read concern after creating the cursor.

Common situations: Sharing readConcern-handling code across find/aggregate/runCommand cursors; building a query abstraction that always sets readConcern.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/de81fc30cd394f63. Report an issue: GitHub.

Appendix: source

Thrown at src/cursor/run_command_cursor.ts:106

  }

  /**
   * Controls the `getMore.batchSize` field
   * @param batchSize - the number documents to return in the `nextBatch`
   */
  public setBatchSize(batchSize: number): this {
    this.getMoreOptions.batchSize = batchSize;
    return this;
  }

  /** Unsupported for RunCommandCursor */
  public override clone(): never {
    throw new MongoAPIError('Clone not supported, create a new cursor with db.runCursorCommand');
  }

  /** Unsupported for RunCommandCursor: readConcern must be configured directly on command document */
  public override withReadConcern(_: ReadConcernLike): never {
    throw new MongoAPIError(
      'RunCommandCursor does not support readConcern it must be attached to the command being run'
    );
  }

  /** Unsupported for RunCommandCursor: various cursor flags must be configured directly on command document */
  public override addCursorFlag(_: string, __: boolean): never {
    throw new MongoAPIError(
      'RunCommandCursor does not support cursor flags, they must be attached to the command being run'
    );
  }

  /**
   * Unsupported for RunCommandCursor: maxTimeMS must be configured directly on command document
   */
  public override maxTimeMS(_: number): never {
    throw new MongoAPIError(
      'maxTimeMS must be configured on the command document directly, to configure getMore.maxTimeMS use cursor.setMaxTimeMS()'
    );

View on GitHub (pinned to dce7939f86)