mongodb/node-mongodb-native · error · MongoRuntimeError
Unexpected null session. A cursor creating command should ha
Error message
Unexpected null session. A cursor creating command should have set this
What it means
A defensive invariant in RunCommandCursor.getMore() that asserts a ClientSession exists. A session is allocated during cursor initialization (the first _read/next), so reaching getMore without one indicates the cursor lifecycle was violated (reused after close, manipulated out of order) or a driver-internal bug. It is a MongoRuntimeError, not user input.
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 3366c21a63)
Solutions
- Do not reuse a RunCommandCursor after it has been closed, completed, or errored
- Create a fresh RunCommandCursor for each independent iteration
- Avoid concurrent iteration of a single cursor instance
- If reproducible on the latest driver version, file a bug with the command and exact lifecycle
Defensive patterns
Strategy: try-catch
Try / catch
try {
await cursor.next();
} catch (err) {
if (err instanceof MongoRuntimeError && /null session/i.test(err.message)) {
// cursor lifecycle is broken; discard and recreate
cursor = db.runCursorCommand(cmd);
} else {
throw err;
}
} Prevention
- Never reuse a cursor after it completes or errors
- Avoid concurrent iteration of the same cursor instance
- Allocate a fresh RunCommandCursor for each independent pass
When it happens
Trigger: Calling getMore after the cursor was closed/killed, reusing a cursor after it errored or completed, concurrent iteration of the same cursor, or a driver regression.
Common situations: Race conditions; manual cursor cleanup; re-entering an async iterator after it threw; driver version mismatches.
Related errors
- Unexpected null session. A cursor creating command should ha
- Unexpected null cursor id. A cursor creating command should
- Unexpected null selectedServer. A cursor creating command sh
- Clone not supported, create a new cursor with db.runCursorCo
- RunCommandCursor does not support readConcern it must be att
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/b02f5e749d2c6261.json.
Report an issue: GitHub.