{"record":{"id":"11212851bc91284b","repo":"mongodb/node-mongodb-native","slug":"use-of-expired-sessions-is-not-permitted","errorCode":null,"errorMessage":"Use of expired sessions is not permitted","messagePattern":"Use of expired sessions is not permitted","errorType":"exception","errorClass":"MongoExpiredSessionError","httpStatus":null,"severity":"error","filePath":"src/operations/execute_operation.ts","lineNumber":88,"sourceCode":"    // TODO(NODE-3483): Extend MongoRuntimeError\n    throw new MongoRuntimeError('This method requires a valid operation instance');\n  }\n\n  const topology =\n    client.topology == null\n      ? await abortable(autoConnect(client), operation.options)\n      : client.topology;\n\n  // The driver sessions spec mandates that we implicitly create sessions for operations\n  // that are not explicitly provided with a session.\n  let session = operation.session;\n  let owner: symbol | undefined;\n\n  if (session == null) {\n    owner = Symbol();\n    session = client.startSession({ owner, explicit: false });\n  } else if (session.hasEnded) {\n    throw new MongoExpiredSessionError('Use of expired sessions is not permitted');\n  } else if (\n    session.snapshotEnabled &&\n    maxWireVersion(topology) < MIN_SUPPORTED_SNAPSHOT_READS_WIRE_VERSION\n  ) {\n    throw new MongoCompatibilityError('Snapshot reads require MongoDB 5.0 or later');\n  } else if (session.client !== client) {\n    throw new MongoInvalidArgumentError('ClientSession must be from the same MongoClient');\n  }\n\n  operation.session ??= session;\n\n  const readPreference = operation.readPreference ?? ReadPreference.primary;\n  const inTransaction = !!session?.inTransaction();\n\n  const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);\n\n  if (\n    inTransaction &&","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/operations/execute_operation.ts#L70-L106","documentation":"Thrown when an operation is executed with a ClientSession that has already been ended (session.hasEnded is true). Sessions are single-use: once endSession() runs (explicitly or via withSession's finally block), the session cannot be reused for further operations.","triggerScenarios":"Keeping a reference to a session from inside client.withSession and using it after the callback returns; calling session.endSession() manually and then passing the same session to another operation; caching sessions across requests.","commonSituations":"Web handlers that store the session on the request object and reuse it after the response; helpers that call endSession too early in a pipeline; misusing withSession by escaping the session via a closure.","solutions":["Do not escape the session from withSession — perform all work inside the callback.","If managing sessions manually, never reuse after endSession(); create a new session with startSession() instead.","Check session.hasEnded before passing to an operation as a defensive guard."],"exampleFix":"// before\nlet saved;\nawait client.withSession(session => { saved = session; });\nawait collection.insertOne({}, { session: saved }); // session has ended\n\n// after\nawait client.withSession(async session => {\n  await collection.insertOne({}, { session });\n});","handlingStrategy":"validation","validationCode":"if (session.hasEnded) {\n  throw new Error('Cannot reuse an ended session');\n}\nawait collection.findOne({}, { session });","typeGuard":"const isLiveSession = (s: { hasEnded?: boolean }): boolean =>\n  s != null && s.hasEnded !== true;","tryCatchPattern":"try {\n  await collection.findOne({}, { session });\n} catch (e) {\n  if (/expired sessions/.test(e.message)) {\n    session = client.startSession();\n    // retry once with a fresh session\n  }\n}","preventionTips":["Do all session work inside withSession's callback.","Never cache or escape sessions across async boundaries."],"tags":["sessions","lifecycle","api-misuse"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}