{"record":{"id":"0f8948638c1e7a09","repo":"nextauthjs/next-auth","slug":"webauthn-user-not-found-in-database-json-string","errorCode":null,"errorMessage":"WebAuthn user not found in database: ${JSON.stringify({credentialID, providerAccountId: authenticator.providerAccountId, userID: account.userId})}","messagePattern":"WebAuthn user not found in database: (.+?)\\)\\}","errorType":"exception","errorClass":"AuthError","httpStatus":null,"severity":"error","filePath":"packages/core/src/lib/utils/webauthn-utils.ts","lineNumber":305,"sourceCode":"  }\n\n  // Get the account and user\n  const account = await adapter.getAccount(\n    authenticator.providerAccountId,\n    provider.id\n  )\n  if (!account) {\n    throw new AuthError(\n      `WebAuthn account not found in database: ${JSON.stringify({\n        credentialID,\n        providerAccountId: authenticator.providerAccountId,\n      })}`\n    )\n  }\n\n  const user = await adapter.getUser(account.userId)\n  if (!user) {\n    throw new AuthError(\n      `WebAuthn user not found in database: ${JSON.stringify({\n        credentialID,\n        providerAccountId: authenticator.providerAccountId,\n        userID: account.userId,\n      })}`\n    )\n  }\n\n  return {\n    account,\n    user,\n  }\n}\n\nexport async function verifyRegister(\n  options: InternalOptions<WebAuthnProviderType>,\n  request: RequestInternal,\n  resCookies: Cookie[]","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/lib/utils/webauthn-utils.ts#L287-L323","documentation":"The account was found, but adapter.getUser(account.userId) returned no user. Since the account row points to a non-existent user, authentication cannot complete and this AuthError is thrown including credentialID, providerAccountId, and the missing userID.","triggerScenarios":"A dangling Account row whose userId references a deleted or never-created User record, encountered during verifyAuthenticate.","commonSituations":"Users hard-deleted without cascading account/authenticator rows; manual DB cleanup; adapters lacking FK constraints allowing orphaned rows; partial backups/restores.","solutions":["Add ON DELETE CASCADE (or cleanup logic) so deleting a user removes its accounts and authenticators","Clean up orphaned Account/Authenticator rows referencing missing users","Verify adapter.getUser is querying the correct users table/ID type","Re-register the passkey to rebuild consistent user/account/authenticator records"],"exampleFix":"// before\n// manual delete left orphan rows\nawait db.user.delete({ where: { id } })\n// after\nawait db.user.delete({ where: { id } }) // with cascade:\n// schema: Account.userId references User.id onDelete: Cascade","handlingStrategy":"validation","validationCode":"const account = await adapter.getAccount(authenticator.providerAccountId, provider.id)\nif (account) {\n  const user = await adapter.getUser(account.userId)\n  if (!user) {\n    // repair or delete the dangling account before authenticating\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await verifyAuthenticate(data)\n} catch (e) {\n  if (e instanceof AuthError && e.message.includes('user not found')) {\n    // remove orphaned account+authenticator rows, re-register\n  }\n}","preventionTips":["Use foreign keys with ON DELETE CASCADE for user-account relations","Avoid hard deletes without cleanup scripts","Validate adapter.getUser ID type (string vs int) against your schema","Run periodic integrity checks for orphaned rows"],"tags":["webauthn","database","user","orphaned-record"],"backgroundTag":"orphaned-account-record","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}