{"record":{"id":"15cde4c8d3371a50","repo":"nextauthjs/next-auth","slug":"invalid-action-parameter","errorCode":null,"errorMessage":"Invalid action parameter","messagePattern":"Invalid action parameter","errorType":"exception","errorClass":"AuthError","httpStatus":null,"severity":"error","filePath":"packages/core/src/lib/actions/callback/index.ts","lineNumber":398,"sourceCode":"\n        const sessionCookies = sessionStore.chunk(newToken, {\n          expires: cookieExpires,\n        })\n\n        cookies.push(...sessionCookies)\n      }\n\n      await events.signIn?.({ user, account })\n\n      return { redirect: callbackUrl, cookies }\n    } else if (provider.type === \"webauthn\" && method === \"POST\") {\n      // Get callback action from request. It should be either \"authenticate\" or \"register\"\n      const action = request.body?.action\n      if (\n        typeof action !== \"string\" ||\n        (action !== \"authenticate\" && action !== \"register\")\n      ) {\n        throw new AuthError(\"Invalid action parameter\")\n      }\n      // Return an error if the adapter is missing or if the provider\n      // is not a webauthn provider.\n      const localOptions = assertInternalOptionsWebAuthn(options)\n\n      // Verify request to get user, account and authenticator\n      let user: User\n      let account: Account\n      let authenticator: Authenticator | undefined\n      switch (action) {\n        case \"authenticate\": {\n          const verified = await verifyAuthenticate(\n            localOptions,\n            request,\n            cookies\n          )\n\n          user = verified.user","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/lib/actions/callback/index.ts#L380-L416","documentation":"AuthError('Invalid action parameter') is thrown by the WebAuthn callback handler when the request body's `action` field is not exactly the string \"authenticate\" or \"register\". The webauthn callback route supports only these two actions, and anything else is rejected before any adapter or provider work happens.","triggerScenarios":"POSTing to /api/auth/callback/webauthn with body.action missing, undefined, a non-string value, or a typo such as \"login\"/\"signup\" instead of \"authenticate\"/\"register\".","commonSituations":"Custom WebAuthn client code calling the internal endpoint directly with a wrong action name; a library version mismatch where the client sends an older action vocabulary; hand-rolled fetch calls forgetting JSON.stringify({ action }) so the body parses without an action field.","solutions":["Send action: \"authenticate\" or action: \"register\" (exact lowercase strings) in the JSON body of the webauthn callback request","Use the official @auth/core browser helpers (e.g. webAuthnFP routines in auth-client) instead of hand-crafted requests","Confirm the request has Content-Type: application/json and a serialized body so request.body?.action is populated","Align client package version with the @auth/core version to avoid protocol drift"],"exampleFix":"// before\nawait fetch(\"/api/auth/callback/webauthn\", { method: \"POST\" })\n// after\nawait fetch(\"/api/auth/callback/webauthn\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({ action: \"authenticate\", ...assertion })\n})","handlingStrategy":"validation","validationCode":"const action = body.action\nif (action !== \"authenticate\" && action !== \"register\") {\n  throw new Error(`Invalid webauthn action: ${action}`)\n}","typeGuard":"function isWebAuthnAction(a: unknown): a is \"authenticate\" | \"register\" {\n  return a === \"authenticate\" || a === \"register\"\n}","tryCatchPattern":"try {\n  await webAuthnAction({ action: \"authenticate\", assertion })\n} catch (e) {\n  if ((e as Error).message.includes(\"Invalid action parameter\")) {\n    // fix request payload: action must be 'authenticate' or 'register'\n  }\n}","preventionTips":["Use the official auth client helpers instead of hand-rolled fetch calls to the webauthn callback","Keep client and @auth/core versions in sync","Always send JSON with Content-Type: application/json","Validate action strings in your client before POSTing"],"tags":["webauthn","validation","request"],"backgroundTag":"invalid-request-parameter","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}