{"record":{"id":"9605308f4cf45512","repo":"mongodb/node-mongodb-native","slug":"unexpected-null-serversession-for-an-ended-implici","errorCode":null,"errorMessage":"Unexpected null serverSession for an ended implicit session","messagePattern":"Unexpected null serverSession for an ended implicit session","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"error","filePath":"src/sessions.ts","lineNumber":221,"sourceCode":"    this.operationTime = undefined;\n    this.owner = options.owner;\n    this.defaultTransactionOptions = { ...options.defaultTransactionOptions };\n    this.transaction = new Transaction();\n  }\n\n  /** The server id associated with this session */\n  get id(): ServerSessionId | undefined {\n    return this.serverSession?.id;\n  }\n\n  get serverSession(): ServerSession {\n    let serverSession = this._serverSession;\n    if (serverSession == null) {\n      if (this.explicit) {\n        throw new MongoRuntimeError('Unexpected null serverSession for an explicit session');\n      }\n      if (this.hasEnded) {\n        throw new MongoRuntimeError('Unexpected null serverSession for an ended implicit session');\n      }\n      serverSession = this.sessionPool.acquire();\n      this._serverSession = serverSession;\n    }\n    return serverSession;\n  }\n\n  get loadBalanced(): boolean {\n    return this.client.topology?.description.type === TopologyType.LoadBalanced;\n  }\n\n  /** @internal */\n  pin(conn: Connection): void {\n    if (this.pinnedConnection) {\n      throw TypeError('Cannot pin multiple connections to the same session');\n    }\n\n    this.pinnedConnection = conn;","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/sessions.ts#L203-L239","documentation":"The `serverSession` getter throws MongoRuntimeError when `_serverSession` is null, the session is implicit, and `hasEnded` is true. Implicit sessions acquire their ServerSession lazily, so after `endSession()` flips `hasEnded` the getter refuses to mint a new server session.","triggerScenarios":"An implicit (driver-created) session being used after `endSession()` — for example, an operation on a cursor whose session was already ended, or calling `session.serverSession` on an ended implicit session.","commonSituations":"Cursors outliving their session; manually ending a session that the driver created implicitly and then running another operation with it; disposing a client while operations are still queued.","solutions":["Let the driver manage implicit sessions; do not call endSession on sessions you did not create with `startSession()`.","Close cursors before ending the session they were created with.","When explicitly managing lifecycle, always pair `startSession()` (explicit) with `endSession()`."],"exampleFix":"// before\nconst cursor = collection.find({}, { session });\nawait session.endSession();\nawait cursor.next(); // throws if session was implicit and ended\n\n// after\nconst docs = await cursor.toArray();\nawait session.endSession();","handlingStrategy":"validation","validationCode":"function ensureAlive(session) {\n  if (session.hasEnded) throw new Error('session ended; cannot use');\n}","typeGuard":"function isUsable(session) {\n  return !session.hasEnded;\n}","tryCatchPattern":null,"preventionTips":["Let the driver own implicit sessions for cursors; do not end them yourself.","Close cursors before ending the session they were created with.","Avoid sharing implicit sessions across concurrent operations."],"tags":["sessions","lifecycle","cursor","implicit-session"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}