[GH-ISSUE #8692] onLinkAccount not triggered for social sign in React Native #11164

Open
opened 2026-04-13 07:31:34 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @flocarle on GitHub (Mar 19, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/8692

Originally assigned to: @bytaesu on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

We’re using better-auth@1.5.5 and @better-auth/expo@1.5.5 in an Expo mobile app that created an anonymous user on boot. On the server, the anonymous plugin is enabled with onLinkAccount.

Steps to reproduce

  1. Open the mobile app with a fresh install or after clearing auth storage.
  2. Let the app finish booting. On launch, it automatically creates an anonymous session.
  3. While still signed in as that anonymous user, go to the mobile sign-in screen.
  4. Tap Continue with Google in the mobile app.
  5. Complete the Google OAuth flow and return to the app through the Expo deep link.
  6. Observe that the social sign-in succeeds and the session changes to the Google user, but the anonymous.onLinkAccount callback is never called.

Current vs. Expected behavior

Current behavior: User linked to the social account is logged in but not linked to the anonymous user
Expected behavior: User linked to the social account is logged in AND onLinkAccount is triggered

What version of Better Auth are you using?

1.5.5

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:55 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T8132",
    "release": "25.3.0",
    "cpuCount": 10,
    "cpuModel": "Apple M4",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.23 GB"
  },
  "node": {
    "version": "v24.2.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "9.11.0"
  },
  "frameworks": null,
  "databases": null,
  "betterAuth": {
    "version": "catalog:",
    "config": null
  }
}

Which area(s) are affected? (Select all that apply)

Client, Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
  plugins: {
    ...
    anonymous({onLinkAccount: () => {...};});
  }
});

Additional context

No response

Originally created by @flocarle on GitHub (Mar 19, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/8692 Originally assigned to: @bytaesu on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce We’re using better-auth@1.5.5 and @better-auth/expo@1.5.5 in an Expo mobile app that created an anonymous user on boot. On the server, the anonymous plugin is enabled with onLinkAccount. Steps to reproduce 1. Open the mobile app with a fresh install or after clearing auth storage. 2. Let the app finish booting. On launch, it automatically creates an anonymous session. 3. While still signed in as that anonymous user, go to the mobile sign-in screen. 4. Tap Continue with Google in the mobile app. 5. Complete the Google OAuth flow and return to the app through the Expo deep link. 6. Observe that the social sign-in succeeds and the session changes to the Google user, but the anonymous.onLinkAccount callback is never called. ### Current vs. Expected behavior Current behavior: User linked to the social account is logged in but not linked to the anonymous user Expected behavior: User linked to the social account is logged in AND onLinkAccount is triggered ### What version of Better Auth are you using? 1.5.5 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:55 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T8132", "release": "25.3.0", "cpuCount": 10, "cpuModel": "Apple M4", "totalMemory": "16.00 GB", "freeMemory": "0.23 GB" }, "node": { "version": "v24.2.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "9.11.0" }, "frameworks": null, "databases": null, "betterAuth": { "version": "catalog:", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Client, Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, plugins: { ... anonymous({onLinkAccount: () => {...};}); } }); ``` ### Additional context _No response_
GiteaMirror added the platformoauthbug labels 2026-04-13 07:31:34 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Mar 19, 2026):

This is a known bug affecting v1.1.18 through v1.5.5. When an anonymous user calls signIn.social(), a new user is created instead of linking to the existing anonymous user, and onLinkAccount never fires.

The issue also affects phone number authentication (#5232) and magic links. The anonymous plugin's after-hook monitors OAuth callbacks but one of its required conditions isn't being satisfied during social sign-in.

Expo-specific check: Make sure you have the expo() server plugin configured—it's required for proper session handling after OAuth in Expo apps:

import { expo } from "@better-auth/expo";

betterAuth({
  plugins: [
    anonymous({ onLinkAccount: async ({ anonymousUser, newUser }) => { /*...*/ } }),
    expo(), // Required for Expo
  ],
  trustedOrigins: ["app://"],
});

Workaround (until the bug is fixed): Enable disableDeleteAnonymousUser: true, then manually handle the linking in onLinkAccount by updating the new Account record's userId to point to the existing anonymous user and deleting the newly created user record.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:4090822020 --> @dosubot[bot] commented on GitHub (Mar 19, 2026): <!-- Answer --> This is a [known bug](https://github.com/better-auth/better-auth/issues/1457) affecting v1.1.18 through v1.5.5. When an anonymous user calls `signIn.social()`, a **new user is created** instead of linking to the existing anonymous user, and `onLinkAccount` never fires. The issue also affects phone number authentication ([#5232](https://github.com/better-auth/better-auth/issues/5232)) and magic links. The [anonymous plugin's after-hook](https://github.com/better-auth/better-auth/blob/a0211a05a6b21cbec8b2639cc063f0d04dc3a690/packages/better-auth/src/plugins/anonymous/index.ts#L234-L326) monitors OAuth callbacks but one of its required conditions isn't being satisfied during social sign-in. **Expo-specific check:** Make sure you have the `expo()` server plugin configured—it's [required for proper session handling](https://github.com/better-auth/better-auth/issues/3711#issuecomment-3149744031) after OAuth in Expo apps: ```typescript import { expo } from "@better-auth/expo"; betterAuth({ plugins: [ anonymous({ onLinkAccount: async ({ anonymousUser, newUser }) => { /*...*/ } }), expo(), // Required for Expo ], trustedOrigins: ["app://"], }); ``` **Workaround** (until the bug is fixed): Enable `disableDeleteAnonymousUser: true`, then manually handle the linking in `onLinkAccount` by updating the new Account record's `userId` to point to the existing anonymous user and deleting the newly created user record. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/8f1dd62a-a064-41be-97b5-369df2f33e53?feedback_type=great_response&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/8f1dd62a-a064-41be-97b5-369df2f33e53?feedback_type=irrelevant_answer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/8f1dd62a-a064-41be-97b5-369df2f33e53?feedback_type=incorrect_sources&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/8f1dd62a-a064-41be-97b5-369df2f33e53?feedback_type=too_verbose&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/8f1dd62a-a064-41be-97b5-369df2f33e53?feedback_type=hallucination&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/8f1dd62a-a064-41be-97b5-369df2f33e53?feedback_type=bug_report&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report) | [Other](https://app.dosu.dev/response-feedback/8f1dd62a-a064-41be-97b5-369df2f33e53?feedback_type=other&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20%5Bknown%20bug%5D%28https%3A//github.com/better-auth/better-auth/issues/1457%29%20affecting%20v1.1.18%20through%20v1.5.5.%20When%20an%20anonymous%20user%20calls%20%60signIn.social%28%29%60%2C%20a%20%2A%2Anew%20user%20is%20created%2A%2A%20instead%20of%20linking%20to%20the%20existing%20anonymous%20user%2C%20and%20%60onLinkAccount%60%20never%20fires.%0A%0AThe%20issue%20also%20affects%20phone%20number%20authentication%20%28%5B%235232%5D%28https%3A//github.com/better-auth/better-auth/issues/5232%29%29%20and%20magic%20links.%20The%20%5Banonymous%20plugin%27s%20after-hook%5D%28https%3A//github.com/better-auth/better-auth/blob/a0211a05a6b21cbec8b2639cc063f0d04dc3a690/packages/better-auth/src/plugins/anonymous/index.ts%23L234-L326%29%20monitors%20OAuth%20callbacks%20but%20one%20of%20its%20required%20conditions%20isn%27t%20being%20satisfied%20during%20social%20sign-in.%0A%0A%2A%2AExpo-specific%20check%3A%2A%2A%20Make%20sure%20you%20have%20the%20%60expo%28%29%60%20server%20plugin%20configured%E2%80%94it%27s%20%5Brequired%20for%20proper%20session%20handling%5D%28https%3A//github.com/better-auth/better-auth/issues/3711%23issuecomment-3149744031%29%20after%20OAuth%20in%20Expo%20apps%3A%0A%0A%60%60%60typescript%0Aimport%20%7B%20expo%20%7D%20from%20%22%40better-auth/expo%22%3B%0A%0AbetterAuth%28%7B%0A%20%20plugins%3A%20%5B%0A%20%20%20%20anonymous%28%7B%20onLinkAccount%3A%20async%20%28%7B%20anonymousUser%2C%20newUser%20%7D%29%20%3D%3E%20%7B%20/%2A...%2A/%20%7D%20%7D%29%2C%0A%20%20%20%20expo%28%29%2C%20//%20Required%20for%20Expo%0A%20%20%5D%2C%0A%20%20trustedOrigins%3A%20%5B%22app%3A//%22%5D%2C%0A%7D%29%3B%0A%60%60%60%0A%0A%2A%2AWorkaround%2A%2A%20%28until%20the%20bug%20is%20fixed%29%3A%20Enable%20%60disableDeleteAnonymousUser%3A%20true%60%2C%20then%20manually%20handle%20the%20linking%20in%20%60onLinkAccount%60%20by%20updating%20the%20new%20Account%20record%27s%20%60userId%60%20to%20point%20to%20the%20existing%20anonymous%20user%20and%20deleting%20the%20newly%20created%20user%20record.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/8692)
Author
Owner

@flocarle commented on GitHub (Mar 19, 2026):

@dosu that workaround won't work because as I said in the issue, onLinkAcount doesn't work

<!-- gh-comment-id:4091468438 --> @flocarle commented on GitHub (Mar 19, 2026): @dosu that workaround won't work because as I said in the issue, `onLinkAcount` doesn't work
Author
Owner

@dosubot[bot] commented on GitHub (Mar 19, 2026):

You're right, apologies for the confusion. Since onLinkAccount never fires at all, the most reliable workaround is to use databaseHooks to intercept account creation at the database level:

betterAuth({
  databaseHooks: {
    account: {
      create: {
        before: async (account, ctx) => {
          const session = ctx?.context?.session;
          if (session?.user?.isAnonymous) {
            // Migrate your anonymous user data here
            await migrateAnonymousData(session.user.id, account.userId);
          }
          return { data: account };
        }
      }
    }
  }
});

This has been confirmed working as an alternative when onLinkAccount fails. The database hooks fire regardless of the OAuth session context issues that cause onLinkAccount to not trigger.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:4091485698 --> @dosubot[bot] commented on GitHub (Mar 19, 2026): <!-- Answer --> You're right, apologies for the confusion. Since `onLinkAccount` never fires at all, the most reliable workaround is to use [`databaseHooks`](https://github.com/better-auth/better-auth/blob/a0211a05a6b21cbec8b2639cc063f0d04dc3a690/packages/better-auth/src/db/with-hooks.ts#L10-L325) to intercept account creation at the database level: ```typescript betterAuth({ databaseHooks: { account: { create: { before: async (account, ctx) => { const session = ctx?.context?.session; if (session?.user?.isAnonymous) { // Migrate your anonymous user data here await migrateAnonymousData(session.user.id, account.userId); } return { data: account }; } } } } }); ``` This [has been confirmed working](https://github.com/better-auth/better-auth/issues/5648#issuecomment-3458223331) as an alternative when `onLinkAccount` fails. The database hooks fire regardless of the OAuth session context issues that cause `onLinkAccount` to not trigger. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/b1f2bffb-580e-44d5-aeb6-bad6d8979b75?feedback_type=great_response&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/b1f2bffb-580e-44d5-aeb6-bad6d8979b75?feedback_type=irrelevant_answer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/b1f2bffb-580e-44d5-aeb6-bad6d8979b75?feedback_type=incorrect_sources&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/b1f2bffb-580e-44d5-aeb6-bad6d8979b75?feedback_type=too_verbose&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/b1f2bffb-580e-44d5-aeb6-bad6d8979b75?feedback_type=hallucination&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/b1f2bffb-580e-44d5-aeb6-bad6d8979b75?feedback_type=bug_report&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report) | [Other](https://app.dosu.dev/response-feedback/b1f2bffb-580e-44d5-aeb6-bad6d8979b75?feedback_type=other&utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=You%27re%20right%2C%20apologies%20for%20the%20confusion.%20Since%20%60onLinkAccount%60%20never%20fires%20at%20all%2C%20the%20most%20reliable%20workaround%20is%20to%20use%20%5B%60databaseHooks%60%5D%28https%3A//github.com/better-auth/better-auth/blob/a0211a05a6b21cbec8b2639cc063f0d04dc3a690/packages/better-auth/src/db/with-hooks.ts%23L10-L325%29%20to%20intercept%20account%20creation%20at%20the%20database%20level%3A%0A%0A%60%60%60typescript%0AbetterAuth%28%7B%0A%20%20databaseHooks%3A%20%7B%0A%20%20%20%20account%3A%20%7B%0A%20%20%20%20%20%20create%3A%20%7B%0A%20%20%20%20%20%20%20%20before%3A%20async%20%28account%2C%20ctx%29%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20session%20%3D%20ctx%3F.context%3F.session%3B%0A%20%20%20%20%20%20%20%20%20%20if%20%28session%3F.user%3F.isAnonymous%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20Migrate%20your%20anonymous%20user%20data%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20migrateAnonymousData%28session.user.id%2C%20account.userId%29%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20return%20%7B%20data%3A%20account%20%7D%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%29%3B%0A%60%60%60%0A%0AThis%20%5Bhas%20been%20confirmed%20working%5D%28https%3A//github.com/better-auth/better-auth/issues/5648%23issuecomment-3458223331%29%20as%20an%20alternative%20when%20%60onLinkAccount%60%20fails.%20The%20database%20hooks%20fire%20regardless%20of%20the%20OAuth%20session%20context%20issues%20that%20cause%20%60onLinkAccount%60%20to%20not%20trigger.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/8692)
Author
Owner

@bytaesu commented on GitHub (Mar 19, 2026):

Hi @flocarle, let me check 🧐

<!-- gh-comment-id:4092540165 --> @bytaesu commented on GitHub (Mar 19, 2026): Hi @flocarle, let me check 🧐
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#11164