mongodb/node-mongodb-native · critical · MongoRuntimeError
Unexpected null selectedServer. A cursor creating command…
Error message
Unexpected null selectedServer. A cursor creating command should have set this
What it means
Thrown as a MongoRuntimeError from getMore() when selectedServer is null/undefined at getMore time. selectedServer is populated during cursorInit() from the InitialCursorResponse returned by _initialize(); a null value here means the cursor creating command never stored the server it selected, which violates the documented contract of the @internal InitialCursorResponse interface. Like the other getMore() guards, this is a driver-internal invariant and indicates a bug rather than user misconfiguration.
Solutions
- If subclassing, ensure _initialize() returns { server, session, response } with a non-null Server.
- Report suspected driver bugs with a reproduction and the driver version.
- Avoid calling the @internal getMore() directly; use the public iteration API.
- Upgrade to the latest patch release.
Defensive patterns
Strategy: try-catch
Try / catch
try {
for await (const doc of cursor) handle(doc);
} catch (err) {
if (err instanceof MongoRuntimeError && /null selectedServer/.test(err.message)) {
// recreate the cursor and retry the read
cursor = collection.find(filter, opts);
} else {
throw err;
}
} Prevention
- Use only the public iteration API so server selection state is managed internally.
- If subclassing, return a non-null Server from _initialize().
- Report suspected driver bugs and keep current with patch releases.
When it happens
Trigger: A subclass's _initialize() returns an InitialCursorResponse without a server; the operation object failed to store its selected server (the TODO(NODE-2882) comment in the file describes this contract); test code constructs a response object manually without a server.
Common situations: Custom cursor subclasses that return incomplete InitialCursorResponse objects; driver bugs where server selection state is lost between operations; instrumentation that strips fields off the response.
Related errors
- Unexpected null cursor id. A cursor creating command should…
- Unexpected null session. A cursor creating command should…
- A collection name must be determined before getMore
- A collection name must be determined before killCursors
- Argument for maxTimeMS must be a number
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/9cab7e9773bf0ebd.
Report an issue: GitHub.
Appendix: source
Thrown at src/cursor/abstract_cursor.ts:866
/**
* Returns a new uninitialized copy of this cursor, with options matching those that have been set on the current instance
*/
abstract clone(): AbstractCursor<TSchema>;
/** @internal */
protected abstract _initialize(
session: ClientSession | undefined
): Promise<InitialCursorResponse>;
/** @internal */
async getMore(): Promise<CursorResponse> {
if (this.cursorId == null) {
throw new MongoRuntimeError(
'Unexpected null cursor id. A cursor creating command should have set this'
);
}
if (this.selectedServer == null) {
throw new MongoRuntimeError(
'Unexpected null selectedServer. A cursor creating command should have set this'
);
}
if (this.cursorSession == null) {
throw new MongoRuntimeError(
'Unexpected null session. A cursor creating command should have set this'
);
}
const getMoreOptions = {
...this.cursorOptions,
session: this.cursorSession,
batchSize: this.cursorOptions.batchSize
};
const getMoreOperation = new GetMoreOperation(
this.cursorNamespace,
this.cursorId,View on GitHub (pinned to dce7939f86)