{"record":{"id":"333c1ca9548f8997","repo":"mongodb/node-mongodb-native","slug":"client-connect-did-not-create-a-topology-but-also","errorCode":null,"errorMessage":"client.connect did not create a topology but also did not throw","messagePattern":"client\\.connect did not create a topology but also did not throw","errorType":"exception","errorClass":"MongoRuntimeError","httpStatus":null,"severity":"error","filePath":"src/operations/execute_operation.ts","lineNumber":153,"sourceCode":"      await session.endSession();\n    }\n  }\n}\n\n/**\n * Connects a client if it has not yet been connected\n * @internal\n */\nexport async function autoConnect(client: MongoClient): Promise<Topology> {\n  if (client.topology == null) {\n    if (client.s.hasBeenClosed) {\n      throw new MongoNotConnectedError('Client must be connected before running operations');\n    }\n    client.s.options.__skipPingOnConnect = true;\n    try {\n      await client.connect();\n      if (client.topology == null) {\n        throw new MongoRuntimeError(\n          'client.connect did not create a topology but also did not throw'\n        );\n      }\n      return client.topology;\n    } finally {\n      delete client.s.options.__skipPingOnConnect;\n    }\n  }\n  return client.topology;\n}\n\n/** @internal */\ntype RetryOptions = {\n  session: ClientSession | undefined;\n  readPreference: ReadPreference;\n  topology: Topology;\n  timeoutContext: TimeoutContext;\n};","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/operations/execute_operation.ts#L135-L171","documentation":"Thrown as a MongoRuntimeError from autoConnect() after await client.connect() resolves successfully yet client.topology is still null. This is a defensive invariant check: connect() is contract-bound to either populate the topology or throw, so reaching this line means the driver is in an impossible internal state. It almost always indicates a concurrent close(), a mocked/improperly overridden connect(), or a genuine driver bug rather than normal user error.","triggerScenarios":"Any operation invoked on a MongoClient that has not yet connected triggers autoConnect (execute_operation.ts:76). If client.close() runs concurrently during that connect, or a test stub of MongoClient.connect() resolves without building a topology, this guard fires at execute_operation.ts:153.","commonSituations":"Calling client.close() in a race with the first operation; unit tests that mock MongoClient.connect() incompletely; a MongoClient subclass that overrides connect() without setting this.s.topology; double-connect/close interleaving in async initialization code.","solutions":["Ensure no concurrent client.close() races with the first operation; await connect() before any operation or before closing.","If mocking MongoClient in tests, make the stub set a topology or throw, matching the real contract.","Avoid calling connect() manually and then operations on the same client from different async branches without awaiting.","If using a real client, upgrade the driver version and report the issue with a reproduction if it persists."],"exampleFix":"// before\nconst client = new MongoClient(uri);\nconst p1 = client.db('x').collection('y').insertOne({a:1}); // triggers autoConnect\nawait client.close(); // races with connect -> error 300\nawait p1;\n\n// after\nconst client = new MongoClient(uri);\nawait client.connect();\ntry {\n  await client.db('x').collection('y').insertOne({a:1});\n} finally {\n  await client.close();\n}","handlingStrategy":"try-catch","validationCode":"// Ensure connect() completes before any concurrent close\nimport type { MongoClient } from 'mongodb';\n\nasync function safeRun(client: MongoClient, fn: () => Promise<void>) {\n  if (client.topology == null) {\n    await client.connect(); // await fully before operating/closing\n  }\n  await fn();\n}","typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n  await client.db('x').collection('y').insertOne({ a: 1 });\n} catch (err) {\n  if (err instanceof MongoRuntimeError && /did not create a topology/.test(err.message)) {\n    // concurrent close or stub issue; reconnect or report\n  } else {\n    throw err;\n  }\n} finally {\n  await client.close();\n}","preventionTips":["Never call client.close() concurrently with the first operation; await connect() first.","Do not partially mock MongoClient.connect() in tests; set a topology or throw.","Treat connect/close as critical sections separated by awaits."],"tags":["runtime","connect","topology","concurrency","internal-invariant"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}