{"record":{"id":"ab9fedce571824f1","repo":"nextauthjs/next-auth","slug":"provider-must-be-webauthn","errorCode":null,"errorMessage":"Provider must be WebAuthn","messagePattern":"Provider must be WebAuthn","errorType":"exception","errorClass":"InvalidProvider","httpStatus":null,"severity":"error","filePath":"packages/core/src/lib/utils/webauthn-utils.ts","lineNumber":492,"sourceCode":"    excludeCredentials: authenticators?.map((a) => ({\n      id: fromBase64(a.credentialID),\n      type: \"public-key\",\n      transports: stringToTransports(a.transports),\n    })),\n  })\n}\n\nexport function assertInternalOptionsWebAuthn(\n  options: InternalOptions\n): InternalOptionsWebAuthn {\n  const { provider, adapter } = options\n\n  // Adapter is required for WebAuthn\n  if (!adapter)\n    throw new MissingAdapter(\"An adapter is required for the WebAuthn provider\")\n  // Provider must be WebAuthn\n  if (!provider || provider.type !== \"webauthn\") {\n    throw new InvalidProvider(\"Provider must be WebAuthn\")\n  }\n  // Narrow the options type for typed usage later\n  return { ...options, provider, adapter }\n}\n\nfunction fromAdapterAuthenticator(\n  authenticator: AdapterAuthenticator\n): InternalAuthenticator {\n  return {\n    ...authenticator,\n    credentialDeviceType:\n      authenticator.credentialDeviceType as InternalAuthenticator[\"credentialDeviceType\"],\n    transports: stringToTransports(authenticator.transports),\n    credentialID: fromBase64(authenticator.credentialID),\n    credentialPublicKey: fromBase64(authenticator.credentialPublicKey),\n  }\n}\n","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/lib/utils/webauthn-utils.ts#L474-L510","documentation":"Auth.js throws InvalidProvider when the provider passed through assertInternalOptionsWebAuthn is missing or its `type` is not \"webauthn\". This guard exists so the rest of the WebAuthn code can rely on a narrowed InternalOptionsWebAuthn type with a correctly typed provider. It indicates the provider routing/wiring is wrong.","triggerScenarios":"localOptions or narrowOptions receiving options where `provider` is undefined, or where provider.type is something other than \"webauthn\" (e.g. \"credentials\", \"oauth\", \"email\") while the WebAuthn assertion path is being exercised.","commonSituations":"Registering the WebAuthn handlers under the wrong provider id in route config; passing a custom provider object that forgot `type: \"webauthn\"`; a refactor renaming/moving providers so the lookup by id returns the wrong or no provider; copy-pasting a provider config and not changing its type.","solutions":["Ensure the provider used for WebAuthn routes is created with `type: \"webauthn\"` (e.g. via the official Passkey/WebAuthn provider helper).","Check that the provider id in the route/URL matches the id of the registered WebAuthn provider.","If using a custom provider object, add the required `type: \"webauthn\"` field and required WebAuthn options.","Verify you are not accidentally passing the whole providers array element of a different kind into the WebAuthn path."],"exampleFix":"// before\nconst provider = { id: \"passkey\", name: \"Passkey\" } // missing type\n// after\nconst provider = {\n  id: \"passkey\",\n  name: \"Passkey\",\n  type: \"webauthn\",\n}","handlingStrategy":"type-guard","validationCode":"if (!provider || provider.type !== \"webauthn\") {\n  throw new Error(`Expected a WebAuthn provider, got: ${provider?.type ?? \"undefined\"}`)\n}","typeGuard":"function isWebAuthnProvider(\n  p: any\n): p is { type: \"webauthn\"; id: string } & Record<string, unknown> {\n  return !!p && p.type === \"webauthn\"\n}","tryCatchPattern":"try {\n  const opts = narrowOptions(options)\n} catch (e) {\n  if (e instanceof InvalidProvider) {\n    throw new ConfigError(\"Route reached WebAuthn handler with a non-webauthn provider — check provider id/type wiring\")\n  }\n  throw e\n}","preventionTips":["Use the official Passkey/WebAuthn provider helper instead of hand-rolled provider objects","Always include type: \"webauthn\" in custom WebAuthn provider definitions","Keep route paths/provider ids consistent between config and handler registration","Type provider registries narrowly so TS flags providers missing the type field"],"tags":["webauthn","provider","configuration","type-narrowing"],"backgroundTag":"invalid-provider-type","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}