{"id":"e084906f3da5af6f","repo":"mongodb/node-mongodb-native","slug":"missing-required-callback-parameter","errorCode":null,"errorMessage":"Missing required callback parameter","messagePattern":"Missing required callback parameter","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/mongo_client.ts","lineNumber":939,"sourceCode":"    options: ClientSessionOptions,\n    executor: WithSessionCallback<T>\n  ): Promise<T>;\n  async withSession<T = any>(\n    optionsOrExecutor: ClientSessionOptions | WithSessionCallback<T>,\n    executor?: WithSessionCallback<T>\n  ): Promise<T> {\n    const options = {\n      // Always define an owner\n      owner: Symbol(),\n      // If it's an object inherit the options\n      ...(typeof optionsOrExecutor === 'object' ? optionsOrExecutor : {})\n    };\n\n    const withSessionCallback =\n      typeof optionsOrExecutor === 'function' ? optionsOrExecutor : executor;\n\n    if (withSessionCallback == null) {\n      throw new MongoInvalidArgumentError('Missing required callback parameter');\n    }\n\n    const session = this.startSession(options);\n\n    try {\n      return await withSessionCallback(session);\n    } finally {\n      try {\n        await session.endSession();\n      } catch (error) {\n        squashError(error);\n      }\n    }\n  }\n\n  /**\n   * Create a new Change Stream, watching for new changes (insertions, updates,\n   * replacements, deletions, and invalidations) in this cluster. Will ignore all","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/mongo_client.ts#L921-L957","documentation":"Thrown by MongoClient.withSession() when no executor callback is provided. withSession has overloads accepting (executor) or (options, executor); if neither resolves to a function, withSessionCallback is null/undefined and the call is rejected as MongoInvalidArgumentError. The callback receives the session and is where your session-scoped work runs.","triggerScenarios":"Calling client.withSession() with no arguments; calling client.withSession({}) with only options and no executor; passing the callback as a non-function (e.g. an options object in both slots).","commonSituations":"Refactoring from callback-style to async code and forgetting the callback; copy-paste errors; calling withSession expecting it to just create and return a session.","solutions":["Always pass a callback: await client.withSession(session => { ... });","Use the two-arg form only when you need options: await client.withSession({ causalConsistency: true }, session => { ... });","If you only need a session handle, use const session = client.startSession() and remember session.endSession()."],"exampleFix":"// before\nawait client.withSession(); // throws\n\n// after\nawait client.withSession(async session => {\n  await collection.insertOne(doc, { session });\n});","handlingStrategy":"validation","validationCode":"function assertWithSessionArgs(optionsOrExecutor, executor) {\n  const cb = typeof optionsOrExecutor === 'function' ? optionsOrExecutor : executor;\n  if (typeof cb !== 'function') throw new TypeError('withSession requires a callback');\n}","typeGuard":"function isFn(v): v is Function { return typeof v === 'function'; }","tryCatchPattern":null,"preventionTips":["Always pass a callback to withSession","Prefer startSession/endSession for explicit control","Type-check options vs callback at call sites"],"tags":["session","callback","api-misuse"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}