[GH-ISSUE #8595] useActiveMemberRole returns previous user's role after sign-out → sign-in #11132

Open
opened 2026-04-13 07:30:09 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @simonsinclair on GitHub (Mar 13, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/8595

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create two users in the same organisation with different roles (e.g., user A is owner, user B is member)
  2. Sign in as user A
  3. Confirm useActiveMemberRole() returns { role: "owner" }
  4. Sign out via authClient.signOut()
  5. Sign in as user B (without refreshing the page)
  6. Read useActiveMemberRole() - it still returns { role: "owner" } (user A's role)
  7. Refresh the page - useActiveMemberRole() now correctly returns { role: "member" }

Current vs. Expected behavior

Current

After signing out and signing in as a different user (SPA navigation, no full page reload), useActiveMemberRole() continues to return the previous user's role.

Expected

useActiveMemberRole() should invalidate/clear their cached data when signOut() completes, so that a subsequent sign-in starts with a clean state.

What version of Better Auth are you using?

1.5.4

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000",
    "release": "24.5.0",
    "cpuCount": 10,
    "cpuModel": "Apple M1 Pro",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.09 GB"
  },
  "node": {
    "version": "v24.13.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.6.2"
  },
  "frameworks": [
    {
      "name": "react",
      "version": "^19.2.4"
    },
    {
      "name": "react-router",
      "version": "^7.13.1"
    }
  ],
  "databases": null,
  "betterAuth": {
    "version": "^1.5.4",
    "config": {}
  }
}

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

Client

Auth config (if applicable)

export const auth = betterAuth({
  basePath: "/auth",
  trustedOrigins: TRUSTED_ORIGINS,
  database: pool,
  disabledPaths: ["/sign-up/email"],
  emailAndPassword: {
    enabled: true,
    disableSignUp: true,
    autoSignIn: false,
  },
  experimental: {
    joins: true,
  },
  databaseHooks: {
    session: {
      create: {
        before: async (session) => {
          // ...
        },
      },
    },
  },
  session: {
    cookieCache: {
      enabled: true,
      maxAge: 5 * 60,
    },
  },
  plugins: [
    organization({
      ac,
      roles: {
        owner,
        admin,
        member,
        // ...
      },
    }),
  ],
});

Additional context

  • Reproducible locally in a React SPA (React 19, React Router 7) - not specific to any browser.
  • useSession() correctly updates after sign-out/sign-in; only the organisation plugin hooks retain stale data.
  • Our workaround is to use hard navigation (window.location.href) on sign-out to destroy all in-memory state.
Originally created by @simonsinclair on GitHub (Mar 13, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/8595 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create two users in the same organisation with different roles (e.g., user A is `owner`, user B is `member`) 2. Sign in as user A 3. Confirm `useActiveMemberRole()` returns `{ role: "owner" }` 4. Sign out via `authClient.signOut()` 5. Sign in as user B (without refreshing the page) 6. Read `useActiveMemberRole()` - it still returns `{ role: "owner" }` (user A's role) 7. Refresh the page - `useActiveMemberRole()` now correctly returns `{ role: "member" }` ### Current vs. Expected behavior #### Current After signing out and signing in as a different user (SPA navigation, no full page reload), `useActiveMemberRole()` continues to return the previous user's role. #### Expected `useActiveMemberRole()` should invalidate/clear their cached data when `signOut()` completes, so that a subsequent sign-in starts with a clean state. ### What version of Better Auth are you using? 1.5.4 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000", "release": "24.5.0", "cpuCount": 10, "cpuModel": "Apple M1 Pro", "totalMemory": "16.00 GB", "freeMemory": "0.09 GB" }, "node": { "version": "v24.13.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.6.2" }, "frameworks": [ { "name": "react", "version": "^19.2.4" }, { "name": "react-router", "version": "^7.13.1" } ], "databases": null, "betterAuth": { "version": "^1.5.4", "config": {} } } ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript export const auth = betterAuth({ basePath: "/auth", trustedOrigins: TRUSTED_ORIGINS, database: pool, disabledPaths: ["/sign-up/email"], emailAndPassword: { enabled: true, disableSignUp: true, autoSignIn: false, }, experimental: { joins: true, }, databaseHooks: { session: { create: { before: async (session) => { // ... }, }, }, }, session: { cookieCache: { enabled: true, maxAge: 5 * 60, }, }, plugins: [ organization({ ac, roles: { owner, admin, member, // ... }, }), ], }); ``` ### Additional context - Reproducible locally in a React SPA (React 19, React Router 7) - not specific to any browser. - `useSession()` correctly updates after sign-out/sign-in; only the organisation plugin hooks retain stale data. - Our workaround is to use hard navigation (`window.location.href`) on sign-out to destroy all in-memory state.
GiteaMirror added the bugorganization labels 2026-04-13 07:30:09 -05:00
Author
Owner

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

Hi @simonsinclair! I'm Dosu and I’m helping the better-auth team.

This is a known issue! The root cause is that activeMemberRole only listens to organization-specific signals ($activeOrgSignal and $activeMemberRoleSignal), but sign-out triggers $sessionSignal instead—so the organization hooks never get notified to invalidate their cache.

There's also a related issue where the spaceSlug cookie isn't cleared on sign-out, causing the previous user's organization context to leak.

Your workaround of calling refetch() after signIn.email() is the recommended approach for now:

await authClient.signIn.email({ email, password });
await refetchRole(); // Force refresh of activeMemberRole

PR #7989 fixed a similar staleness issue when switching organizations, but it doesn't cover the sign-out scenario since sign-out doesn't trigger the organization-specific signals.

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:4056788476 --> @dosubot[bot] commented on GitHub (Mar 13, 2026): <!-- Greeting --> Hi @simonsinclair! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known issue! The root cause is that `activeMemberRole` only listens to organization-specific signals (`$activeOrgSignal` and `$activeMemberRoleSignal`), but **sign-out triggers `$sessionSignal`** instead—so the [organization hooks never get notified to invalidate their cache](https://github.com/better-auth/better-auth/blob/db5a44424f5747c47a7da347613e42b664e1e734/packages/better-auth/src/plugins/organization/client.ts#L212-L219). There's also a related issue where the [`spaceSlug` cookie isn't cleared on sign-out](https://github.com/better-auth/better-auth/issues/8557), causing the previous user's organization context to leak. Your workaround of calling `refetch()` after `signIn.email()` is the recommended approach for now: ```typescript await authClient.signIn.email({ email, password }); await refetchRole(); // Force refresh of activeMemberRole ``` [PR #7989](https://github.com/better-auth/better-auth/pull/7989) fixed a similar staleness issue when switching organizations, but it doesn't cover the sign-out scenario since sign-out doesn't trigger the organization-specific signals. <!-- 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/0365d391-3367-4f18-9efa-f1790aa17612?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/0365d391-3367-4f18-9efa-f1790aa17612?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/0365d391-3367-4f18-9efa-f1790aa17612?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/0365d391-3367-4f18-9efa-f1790aa17612?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/0365d391-3367-4f18-9efa-f1790aa17612?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/0365d391-3367-4f18-9efa-f1790aa17612?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/0365d391-3367-4f18-9efa-f1790aa17612?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%20known%20issue%21%20The%20root%20cause%20is%20that%20%60activeMemberRole%60%20only%20listens%20to%20organization-specific%20signals%20%28%60%24activeOrgSignal%60%20and%20%60%24activeMemberRoleSignal%60%29%2C%20but%20%2A%2Asign-out%20triggers%20%60%24sessionSignal%60%2A%2A%20instead%E2%80%94so%20the%20%5Borganization%20hooks%20never%20get%20notified%20to%20invalidate%20their%20cache%5D%28https%3A//github.com/better-auth/better-auth/blob/db5a44424f5747c47a7da347613e42b664e1e734/packages/better-auth/src/plugins/organization/client.ts%23L212-L219%29.%0A%0AThere%27s%20also%20a%20related%20issue%20where%20the%20%5B%60spaceSlug%60%20cookie%20isn%27t%20cleared%20on%20sign-out%5D%28https%3A//github.com/better-auth/better-auth/issues/8557%29%2C%20causing%20the%20previous%20user%27s%20organization%20context%20to%20leak.%0A%0AYour%20workaround%20of%20calling%20%60refetch%28%29%60%20after%20%60signIn.email%28%29%60%20is%20the%20recommended%20approach%20for%20now%3A%0A%0A%60%60%60typescript%0Aawait%20authClient.signIn.email%28%7B%20email%2C%20password%20%7D%29%3B%0Aawait%20refetchRole%28%29%3B%20//%20Force%20refresh%20of%20activeMemberRole%0A%60%60%60%0A%0A%5BPR%20%237989%5D%28https%3A//github.com/better-auth/better-auth/pull/7989%29%20fixed%20a%20similar%20staleness%20issue%20when%20switching%20organizations%2C%20but%20it%20doesn%27t%20cover%20the%20sign-out%20scenario%20since%20sign-out%20doesn%27t%20trigger%20the%20organization-specific%20signals.)&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/8595)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#11132