{"record":{"id":"ea116dc6595f5a4c","repo":"mongodb/node-mongodb-native","slug":"unexpected-null-serversession-for-an-explicit-sess","errorCode":null,"errorMessage":"Unexpected null serverSession for an explicit session","messagePattern":"Unexpected null serverSession for an explicit session","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"error","filePath":"src/sessions.ts","lineNumber":218,"sourceCode":"\n    this.clusterTime = options.initialClusterTime;\n\n    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');","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/sessions.ts#L200-L236","documentation":"The `serverSession` getter throws MongoRuntimeError when `_serverSession` is null on an explicit session. Explicit sessions acquire their ServerSession at construction (sessions.ts:192), so a null one implies the session is in an invalid lifecycle state — typically used after its server session was released or never properly acquired.","triggerScenarios":"Accessing `session.serverSession` (directly or via an operation) after `endSession()` has released it; a half-constructed session from a failed `startSession`; an internal race that released the server session prematurely.","commonSituations":"Reusing a session after `await session.endSession()`; sharing a session across concurrent code paths where one calls endSession; storing sessions in long-lived singletons that get cleaned up elsewhere.","solutions":["Treat `endSession()` as terminal: never reuse the session afterward.","Use `try/finally` to scope a session: `const s = client.startSession(); try { ... } finally { await s.endSession(); }`.","If pooling sessions in a wrapper, mark them ended and reject further use rather than handing them out again."],"exampleFix":"// before\nconst session = client.startSession();\nawait session.endSession();\nawait collection.findOne({}, { session }); // throws\n\n// after\nconst session = client.startSession();\ntry {\n  await collection.findOne({}, { session });\n} finally {\n  await session.endSession();\n}","handlingStrategy":"try-catch","validationCode":"function assertUsable(session) {\n  if (session.hasEnded) throw new Error('session has ended; obtain a new one');\n}","typeGuard":"function isActive(session) {\n  return !session.hasEnded;\n}","tryCatchPattern":"try {\n  await collection.findOne({}, { session });\n} catch (err) {\n  if (err.name === 'MongoRuntimeError' && /explicit session/i.test(err.message)) {\n    // session was ended; restart with a fresh one\n    session = client.startSession();\n  }\n}","preventionTips":["Scope every explicit session in try/finally and end it once.","Never reuse a session across async boundaries after endSession.","Track session lifecycle in a wrapper that prevents post-end use."],"tags":["sessions","lifecycle","internal"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}