{"record":{"id":"4129a578bb7cdae4","repo":"nextauthjs/next-auth","slug":"the-account-is-already-associated-with-another-use","errorCode":null,"errorMessage":"The account is already associated with another user","messagePattern":"The account is already associated with another user","errorType":"exception","errorClass":"AccountNotLinked","httpStatus":null,"severity":"error","filePath":"packages/core/src/lib/actions/callback/handle-login.ts","lineNumber":144,"sourceCode":"\n    return { session, user, isNewUser }\n  } else if (account.type === \"webauthn\") {\n    // Check if the account exists\n    const userByAccount = await getUserByAccount({\n      providerAccountId: account.providerAccountId,\n      provider: account.provider,\n    })\n    if (userByAccount) {\n      if (user) {\n        // If the user is already signed in with this account, we don't need to do anything\n        if (userByAccount.id === user.id) {\n          const currentAccount: AdapterAccount = { ...account, userId: user.id }\n          return { session, user, isNewUser, account: currentAccount }\n        }\n        // If the user is currently signed in, but the new account they are signing in\n        // with is already associated with another user, then we cannot link them\n        // and need to return an error.\n        throw new AccountNotLinked(\n          \"The account is already associated with another user\",\n          { provider: account.provider }\n        )\n      }\n      // If there is no active session, but the account being signed in with is already\n      // associated with a valid user then create session to sign the user in.\n      session = useJwtSession\n        ? {}\n        : await createSession({\n            sessionToken: generateSessionToken(),\n            userId: userByAccount.id,\n            expires: fromDate(options.session.maxAge),\n          })\n\n      const currentAccount: AdapterAccount = {\n        ...account,\n        userId: userByAccount.id,\n      }","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/lib/actions/callback/handle-login.ts#L126-L162","documentation":"An AccountNotLinked error thrown when the user is already signed in and tries to link a new OAuth account, but that provider account (same provider + providerAccountId) is already linked to a different user in the database. Auth.js refuses to link it to avoid merging accounts, throwing at handle-login.ts:144.","triggerScenarios":"Signing in with the same OAuth account under a second, different user session while allowDangerousEmailAccountLinking is off; two local users each having previously linked the same external account; database state where the account row's userId points to another user.","commonSituations":"Testing with the same Google/GitHub account across two test users; staging databases seeded with the same OAuth account on multiple users; switching auth providers and reusing a database with stale account rows.","solutions":["Remove the conflicting account row from your adapter's accounts table (or unlink it via your adapter) so it can be linked to the current user.","Sign in with the user that already owns the OAuth account instead of creating a second one.","If email-verified linking is acceptable, set allowDangerousEmailAccountLinking: true on the provider.","Clean up duplicate users in the database and enforce one-account-per-user linking rules."],"exampleFix":"// before\nGoogle({ clientId, clientSecret })\n// after (only if you understand the security tradeoff)\nGoogle({ clientId, clientSecret, allowDangerousEmailAccountLinking: true })","handlingStrategy":"try-catch","validationCode":"// Before offering account linking in your UI, check ownership:\nconst existing = await adapter.getAccountByProviderAccountId(provider, providerAccountId)\nif (existing && existing.userId !== session.user.id) {\n  throw new Error('This account is already linked to another user')\n}","typeGuard":null,"tryCatchPattern":"try {\n  await signIn(providerId)\n} catch (e) {\n  if (e instanceof AccountNotLinked) {\n    // show 'account already linked to another user' message / support path\n  }\n}","preventionTips":["Add a unique constraint on (provider, provider_account_id) in your accounts table.","Provide an unlink-account UI backed by your adapter.","Decide explicitly whether to enable allowDangerousEmailAccountLinking.","Clean duplicate users from seeded/staging databases regularly."],"tags":["oauth","account-linking","database","authjs"],"backgroundTag":"account-not-linked","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}