{"record":{"id":"b02f5e749d2c6261","repo":"mongodb/node-mongodb-native","slug":"unexpected-null-session-a-cursor-creating-command-b02f5e","errorCode":null,"errorMessage":"Unexpected null session. A cursor creating command should have set this","messagePattern":"Unexpected null session\\. A cursor creating command should have set this","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"error","filePath":"src/cursor/run_command_cursor.ts","lineNumber":164,"sourceCode":"    const operation = new RunCursorCommandOperation(this.db.s.namespace, this.command, {\n      ...this.cursorOptions,\n      session: session,\n      readPreference: this.cursorOptions.readPreference\n    });\n\n    const response = await executeOperation(this.client, operation, this.timeoutContext);\n\n    return {\n      server: operation.server,\n      session,\n      response\n    };\n  }\n\n  /** @internal */\n  override async getMore(): Promise<CursorResponse> {\n    if (!this.session) {\n      throw new MongoRuntimeError(\n        'Unexpected null session. A cursor creating command should have set this'\n      );\n    }\n\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const getMoreOperation = new GetMoreOperation(this.namespace, this.id!, this.server!, {\n      ...this.cursorOptions,\n      session: this.session,\n      ...this.getMoreOptions\n    });\n\n    return await executeOperation(this.client, getMoreOperation, this.timeoutContext);\n  }\n}\n","sourceCodeStart":146,"sourceCodeEnd":179,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cursor/run_command_cursor.ts#L146-L179","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Ensure the cursor is iterated normally via for-await or .next() so _initialize attaches the session.","Do not reuse a cursor after close(); create a fresh one via db.runCursorCommand.","Upgrade the driver to the latest patch release if hitting this on an older version, as it usually indicates a fixed internal bug.","Avoid sharing a single cursor across concurrent consumers."],"exampleFix":"// before\nconst cursor = db.runCursorCommand(cmd);\ncursor.close();\nawait cursor.next(); // session is null\n\n// after\nconst cursor = db.runCursorCommand(cmd);\nfor await (const doc of cursor) {\n  if (done) { await cursor.close(); break; }\n  handle(doc);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await cursor.next();\n} catch (e) {\n  if (e instanceof MongoRuntimeError && /Unexpected null session/.test(e.message)) {\n    // cursor is not in an initialized state: recreate it\n    cursor = db.runCursorCommand(cmd, opts);\n  } else throw e;\n}","preventionTips":["Never reuse a cursor after close(); create a new one via db.runCursorCommand.","Iterate cursors with for-await so _initialize runs exactly once and attaches the session.","Do not share a cursor across concurrent consumers; serialize access or open one per consumer.","Upgrade to the latest driver patch if hitting this on an older version, as it usually signals an internal lifecycle bug."],"tags":["run-command-cursor","session","internal-error","lifecycle"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}