{"id":"9cab7e9773bf0ebd","repo":"mongodb/node-mongodb-native","slug":"unexpected-null-selectedserver-a-cursor-creating","errorCode":null,"errorMessage":"Unexpected null selectedServer. A cursor creating command should have set this","messagePattern":"Unexpected null selectedServer\\. A cursor creating command should have set this","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"error","filePath":"src/cursor/abstract_cursor.ts","lineNumber":866,"sourceCode":"  /**\n   * Returns a new uninitialized copy of this cursor, with options matching those that have been set on the current instance\n   */\n  abstract clone(): AbstractCursor<TSchema>;\n\n  /** @internal */\n  protected abstract _initialize(\n    session: ClientSession | undefined\n  ): Promise<InitialCursorResponse>;\n\n  /** @internal */\n  async getMore(): Promise<CursorResponse> {\n    if (this.cursorId == null) {\n      throw new MongoRuntimeError(\n        'Unexpected null cursor id. A cursor creating command should have set this'\n      );\n    }\n    if (this.selectedServer == null) {\n      throw new MongoRuntimeError(\n        'Unexpected null selectedServer. A cursor creating command should have set this'\n      );\n    }\n\n    if (this.cursorSession == null) {\n      throw new MongoRuntimeError(\n        'Unexpected null session. A cursor creating command should have set this'\n      );\n    }\n    const getMoreOptions = {\n      ...this.cursorOptions,\n      session: this.cursorSession,\n      batchSize: this.cursorOptions.batchSize\n    };\n\n    const getMoreOperation = new GetMoreOperation(\n      this.cursorNamespace,\n      this.cursorId,","sourceCodeStart":848,"sourceCodeEnd":884,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/cursor/abstract_cursor.ts#L848-L884","documentation":"Thrown by AbstractCursor.getMore() when selectedServer is null while dispatching a getMore. selectedServer is populated during cursorInit() from the _initialize() result (abstract_cursor.ts:915) and is required to route the getMore to the correct server. Like the null cursorId check, this should be unreachable through public iteration APIs because cursorInit() runs before getMore() in fetchBatch().","triggerScenarios":"A custom _initialize() implementation that returns an InitialCursorResponse without a server field, or direct invocation of the @internal getMore() before the cursor has been initialized. Also theoretically possible if server selection was somehow stripped after init.","commonSituations":"Custom cursor subclasses, test harnesses that stub _initialize() incompletely, or integration with mock libraries that replace the init response object.","solutions":["Ensure any custom _initialize() returns a real server object (e.g. AggregateOperation/FindOperation .server after executeOperation)","Do not invoke the internal getMore() directly; iterate via next()/for-await/toArray()","Verify you are not reusing a cursor instance whose server reference was cleared by cleanup()"],"exampleFix":"// before\nasync _initialize(session) {\n  const resp = await executeOperation(this.client, op);\n  return { response: resp, session }; // missing server\n}\n// after\nasync _initialize(session) {\n  const resp = await executeOperation(this.client, op);\n  return { response: resp, server: op.server, session };\n}","handlingStrategy":"validation","validationCode":"// Validate custom _initialize output before returning it\nasync _initialize(session) {\n  const response = await executeOperation(this.client, op);\n  if (!op.server) throw new Error('no server selected');\n  return { response, server: op.server, session };\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure custom _initialize() returns the server from the executed operation","Iterate via public next()/toArray() so cursorInit() runs first","Avoid direct calls to internal getMore()"],"tags":["cursor","internal","getmore","driver-bug"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}