{"id":"9a4f2ef0efba36d8","repo":"mongodb/node-mongodb-native","slug":"clientsession-must-be-from-the-same-mongoclient","errorCode":null,"errorMessage":"ClientSession must be from the same MongoClient","messagePattern":"ClientSession must be from the same MongoClient","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/operations/execute_operation.ts","lineNumber":95,"sourceCode":"      : 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 &&\n    !readPreference.equals(ReadPreference.primary) &&\n    (hasReadAspect || operation.commandName === 'runCommand')\n  ) {\n    throw new MongoTransactionError(\n      `Read preference in a transaction must be primary, not: ${readPreference.mode}`\n    );\n  }","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/operations/execute_operation.ts#L77-L113","documentation":"executeOperation (src/operations/execute_operation.ts:95) throws a MongoInvalidArgumentError when the ClientSession supplied to an operation was created by a different MongoClient instance (session.client !== client). Sessions are bound to the client that created them because they carry cluster time, server pinning, and transaction state tied to that client's topology.","triggerScenarios":"Creating a session with clientA.startSession() and passing it to a collection or operation obtained from clientB (a different MongoClient).","commonSituations":"Multi-tenant applications with one client per tenant, connection-pool reuse bugs, or refactors that swap MongoClient instances without updating session creation.","solutions":["Ensure the session is created by the same MongoClient whose collection/db you are calling the operation on.","Pass the client explicitly or derive sessions from the client that owns the collection.","Audit code where multiple MongoClient instances coexist and verify session provenance."],"exampleFix":"// before\nconst session = clientA.startSession();\nawait clientB.db('app').collection('users').insertOne({}, { session }); // throws\n\n// after\nconst session = clientB.startSession();\nawait clientB.db('app').collection('users').insertOne({}, { session });","handlingStrategy":"validation","validationCode":"function assertSessionOwner(session: ClientSession, client: MongoClient): void {\n  if (session.client !== client) {\n    throw new Error('Session was created by a different MongoClient');\n  }\n}\n// usage:\nassertSessionOwner(session, client);","typeGuard":"const sessionBelongsTo = (session: ClientSession, client: MongoClient): boolean =>\n  session.client === client;","tryCatchPattern":null,"preventionTips":["Derive sessions from the same MongoClient whose collections you use.","Avoid passing sessions across client boundaries in multi-tenant code.","Centralize session creation near the client that owns the workload."],"tags":["session","client-binding","argument-validation"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}