mongodb/node-mongodb-native · error · MongoRuntimeError

Unexpected null session. A cursor creating command should…

Error message

Unexpected null session. A cursor creating command should have set this

What it means

Thrown by RunCommandCursor.getMore when this.session is null at the time a getMore is sent. A cursor that has been initialized must have an implicit or explicit session attached by AbstractCursor; a null session here means the cursor was never successfully initialized, was closed, or the session was cleared by an external path. This is a MongoRuntimeError indicating driver-internal state corruption rather than user misuse.

Solutions

  1. Ensure the cursor is iterated normally via for-await or .next() so _initialize attaches the session.
  2. Do not reuse a cursor after close(); create a fresh one via db.runCursorCommand.
  3. Upgrade the driver to the latest patch release if hitting this on an older version, as it usually indicates a fixed internal bug.
  4. Avoid sharing a single cursor across concurrent consumers.

Example fix

// before
const cursor = db.runCursorCommand(cmd);
cursor.close();
await cursor.next(); // session is null

// after
const cursor = db.runCursorCommand(cmd);
for await (const doc of cursor) {
  if (done) { await cursor.close(); break; }
  handle(doc);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await cursor.next();
} catch (e) {
  if (e instanceof MongoRuntimeError && /Unexpected null session/.test(e.message)) {
    // cursor is not in an initialized state: recreate it
    cursor = db.runCursorCommand(cmd, opts);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling cursor.next() / iterating a RunCommandCursor whose _initialize never ran (e.g. bypassed via internal API); iterating a cursor after it was closed and its session released; concurrent close() racing with getMore().

Common situations: Custom cursor wrappers that skip AbstractCursor initialization; bugs in older driver versions around session cleanup; concurrent consumers racing close() and next() on the same cursor.

Related errors


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

Appendix: source

Thrown at src/cursor/run_command_cursor.ts:164

    const operation = new RunCursorCommandOperation(this.db.s.namespace, this.command, {
      ...this.cursorOptions,
      session: session,
      readPreference: this.cursorOptions.readPreference
    });

    const response = await executeOperation(this.client, operation, this.timeoutContext);

    return {
      server: operation.server,
      session,
      response
    };
  }

  /** @internal */
  override async getMore(): Promise<CursorResponse> {
    if (!this.session) {
      throw new MongoRuntimeError(
        'Unexpected null session. A cursor creating command should have set this'
      );
    }

    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    const getMoreOperation = new GetMoreOperation(this.namespace, this.id!, this.server!, {
      ...this.cursorOptions,
      session: this.session,
      ...this.getMoreOptions
    });

    return await executeOperation(this.client, getMoreOperation, this.timeoutContext);
  }
}

View on GitHub (pinned to dce7939f86)