[GH-ISSUE #4810] authClient: organization.checkSlug() causes useActiveOrganization() isPending to flip true temporarily on each check #10080

Closed
opened 2026-04-13 05:59:46 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @shahaayush1999 on GitHub (Sep 22, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/4810

Originally assigned to: @ping-maxwell on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create a better-auth endpoint with any framework, set up the organization plugin
  2. In the frontend, gate the UI behind useSession (if no session, show sign-in form) and useActiveOrganization (if no organization, show a create organization form)
  3. For a signed-in user with no organization, on the create org form, run authClient.organization.checkSlug({ slug }) to check if a slug is available/taken
  4. The slug check flips the isPending for useActiveOrganization hook momentarily, causing the UI to re-render the page and again showing the user a fresh create organization page, thus leaving the user to be unable to create an organization.

Current vs. Expected behavior

Current behaviour: authClient.organization.checkSlug() flips isPending of authClient.useActiveOrganization() hook to be true momentarily
Expected behaviour: Checking slug availability should not have any side effects (i.e. on useActiveOrganization hook)

What version of Better Auth are you using?

1.3.13

System info

aayush@Aayushs-MacBook-Pro zennoia-monolith % bunx @better-auth/cli info --json 
{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.0.0: Mon Aug 25 21:17:54 PDT 2025; root:xnu-12377.1.9~3/RELEASE_ARM64_T6041",
    "release": "25.0.0",
    "cpuCount": 12,
    "cpuModel": "Apple M4 Pro",
    "totalMemory": "24.00 GB",
    "freeMemory": "2.06 GB"
  },
  "node": {
    "version": "v22.14.0",
    "env": "development"
  },
  "packageManager": {
    "name": "bun",
    "version": "1.2.22"
  },
  "frameworks": [
    {
      "name": "react",
      "version": "^19.1.1"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "^8.13.1"
    },
    {
      "name": "drizzle",
      "version": "^0.44.4"
    }
  ],
  "betterAuth": {
    "version": "^1.3.13",
    "config": null
  }
}

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

Client

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { organization, emailOTP } from "better-auth/plugins";
import { db } from "../db";
import { getFirstOrganizationId } from "./auth-helpers";
import { sendSignInOTP } from "./email/templates/sign-in-otp";
import * as dbSchema from "@/server/db/schema/auth";
import { BACKEND_URL, getServerConfig } from "@/lib/config";

const {
  googleClientId,
  googleClientSecret,
  microsoftClientId,
  microsoftClientSecret,
  betterAuthSecret,
} = getServerConfig();

export const auth = betterAuth({
  secret: betterAuthSecret,
  baseURL: `${BACKEND_URL}/api/auth`,
  database: drizzleAdapter(db, {
    provider: "pg",
    schema: dbSchema,
  }),
  socialProviders: {
    google: {
      clientId: googleClientId,
      clientSecret: googleClientSecret,
    },
    microsoft: {
      clientId: microsoftClientId,
      clientSecret: microsoftClientSecret,
    },
  },
  session: {
    cookieCache: {
      enabled: true,
      maxAge: 5 * 60, // Cache duration in seconds
    },
  },
  plugins: [
    organization({
      async sendInvitationEmail() {
        // Return early to prevent Better Auth from sending emails
        // We handle email sending in our custom tRPC endpoint
        return;
      },
    }),
    emailOTP({
      async sendVerificationOTP({ email, otp, type }) {
        if (type === "sign-in") {
          await sendSignInOTP(email, otp);
        }
      },
    }),
  ],
  databaseHooks: {
    session: {
      create: {
        before: async (session) => {
          const orgId = await getFirstOrganizationId(session.userId);
          if (orgId === null) {
            return {
              data: session,
            };
          }

          return {
            data: {
              ...session,
              activeOrganizationId: orgId,
            },
          };
        },
      },
    },
  },
  telemetry: {
    enabled: false,
  },
});

Additional context

  • Tested repro on the latest release at the time of filing this issue (1.3.13).
  • No existing open issues related to checkSlug.
Originally created by @shahaayush1999 on GitHub (Sep 22, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/4810 Originally assigned to: @ping-maxwell on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create a better-auth endpoint with any framework, set up the organization plugin 2. In the frontend, gate the UI behind useSession (if no session, show sign-in form) and useActiveOrganization (if no organization, show a create organization form) 3. For a signed-in user with no organization, on the create org form, run authClient.organization.checkSlug({ slug }) to check if a slug is available/taken 4. The slug check flips the isPending for useActiveOrganization hook momentarily, causing the UI to re-render the page and again showing the user a fresh create organization page, thus leaving the user to be unable to create an organization. ### Current vs. Expected behavior Current behaviour: authClient.organization.checkSlug() flips isPending of authClient.useActiveOrganization() hook to be true momentarily Expected behaviour: Checking slug availability should not have any side effects (i.e. on useActiveOrganization hook) ### What version of Better Auth are you using? 1.3.13 ### System info ```bash aayush@Aayushs-MacBook-Pro zennoia-monolith % bunx @better-auth/cli info --json { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.0.0: Mon Aug 25 21:17:54 PDT 2025; root:xnu-12377.1.9~3/RELEASE_ARM64_T6041", "release": "25.0.0", "cpuCount": 12, "cpuModel": "Apple M4 Pro", "totalMemory": "24.00 GB", "freeMemory": "2.06 GB" }, "node": { "version": "v22.14.0", "env": "development" }, "packageManager": { "name": "bun", "version": "1.2.22" }, "frameworks": [ { "name": "react", "version": "^19.1.1" } ], "databases": [ { "name": "pg", "version": "^8.13.1" }, { "name": "drizzle", "version": "^0.44.4" } ], "betterAuth": { "version": "^1.3.13", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { organization, emailOTP } from "better-auth/plugins"; import { db } from "../db"; import { getFirstOrganizationId } from "./auth-helpers"; import { sendSignInOTP } from "./email/templates/sign-in-otp"; import * as dbSchema from "@/server/db/schema/auth"; import { BACKEND_URL, getServerConfig } from "@/lib/config"; const { googleClientId, googleClientSecret, microsoftClientId, microsoftClientSecret, betterAuthSecret, } = getServerConfig(); export const auth = betterAuth({ secret: betterAuthSecret, baseURL: `${BACKEND_URL}/api/auth`, database: drizzleAdapter(db, { provider: "pg", schema: dbSchema, }), socialProviders: { google: { clientId: googleClientId, clientSecret: googleClientSecret, }, microsoft: { clientId: microsoftClientId, clientSecret: microsoftClientSecret, }, }, session: { cookieCache: { enabled: true, maxAge: 5 * 60, // Cache duration in seconds }, }, plugins: [ organization({ async sendInvitationEmail() { // Return early to prevent Better Auth from sending emails // We handle email sending in our custom tRPC endpoint return; }, }), emailOTP({ async sendVerificationOTP({ email, otp, type }) { if (type === "sign-in") { await sendSignInOTP(email, otp); } }, }), ], databaseHooks: { session: { create: { before: async (session) => { const orgId = await getFirstOrganizationId(session.userId); if (orgId === null) { return { data: session, }; } return { data: { ...session, activeOrganizationId: orgId, }, }; }, }, }, }, telemetry: { enabled: false, }, }); ``` ### Additional context - Tested repro on the latest release at the time of filing this issue (1.3.13). - No existing open issues related to checkSlug.
GiteaMirror added the bugorganization labels 2026-04-13 05:59:46 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 22, 2025):

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

Yes, this is suited for GitHub. The behavior you described—where calling authClient.organization.checkSlug() causes useActiveOrganization().isPending to flip true temporarily—is not expected and is likely a side effect of shared state or cache between organization-related hooks and methods. This can cause UI flicker or reloads, as you've seen.

There are no existing open issues or documentation addressing this specific interaction. The root cause is probably that both checkSlug and useActiveOrganization share organization state or cache (possibly via React Query or a similar mechanism), so a network request from checkSlug may trigger a refetch or invalidate the cache for useActiveOrganization, causing its isPending state to flip momentarily. There are no built-in options or config to isolate the cache or query keys for these calls in the current version (source).

Some users have worked around similar issues by ignoring or not using the isPending state in their UI, but this is not a true fix. If you need a workaround, you could debounce checkSlug calls or avoid gating UI logic directly on isPending until this is addressed in the library.

This is a valid issue for maintainers to review, as it impacts user experience and is not documented or tracked elsewhere.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3317634897 --> @dosubot[bot] commented on GitHub (Sep 22, 2025): <!-- Greeting --> Hi @shahaayush1999! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> Yes, this is suited for GitHub. The behavior you described—where calling `authClient.organization.checkSlug()` causes `useActiveOrganization().isPending` to flip true temporarily—is not expected and is likely a side effect of shared state or cache between organization-related hooks and methods. This can cause UI flicker or reloads, as you've seen. There are no existing open issues or documentation addressing this specific interaction. The root cause is probably that both `checkSlug` and `useActiveOrganization` share organization state or cache (possibly via React Query or a similar mechanism), so a network request from `checkSlug` may trigger a refetch or invalidate the cache for `useActiveOrganization`, causing its `isPending` state to flip momentarily. There are no built-in options or config to isolate the cache or query keys for these calls in the current version ([source](https://github.com/better-auth/better-auth/issues/1713#issuecomment-2705357999)). Some users have worked around similar issues by ignoring or not using the `isPending` state in their UI, but this is not a true fix. If you need a workaround, you could debounce `checkSlug` calls or avoid gating UI logic directly on `isPending` until this is addressed in the library. This is a valid issue for maintainers to review, as it impacts user experience and is not documented or tracked elsewhere. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/d4e62463-e866-448f-95d2-dbcaad13ebcb?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d4e62463-e866-448f-95d2-dbcaad13ebcb?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d4e62463-e866-448f-95d2-dbcaad13ebcb?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d4e62463-e866-448f-95d2-dbcaad13ebcb?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d4e62463-e866-448f-95d2-dbcaad13ebcb?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d4e62463-e866-448f-95d2-dbcaad13ebcb?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d4e62463-e866-448f-95d2-dbcaad13ebcb?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&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/4810)
Author
Owner

@dvanmali commented on GitHub (Sep 23, 2025):

Hi @shahaayush1999, if possible, could you provide a minimal repo to help debug?

<!-- gh-comment-id:3322398741 --> @dvanmali commented on GitHub (Sep 23, 2025): Hi @shahaayush1999, if possible, could you provide a minimal repo to help debug?
Author
Owner

@shahaayush1999 commented on GitHub (Sep 23, 2025):

Hi @dvanmali , I've set up a minimal repro environment that you can clone and run easily. README.md has the steps for your convenience. The environment where I'm facing this bug is Tanstack Start, but this bug seems to be framework agnostic, so I used a template with hono backend + react frontend where this bug also reproduces

https://github.com/shahaayush1999/check-slug-minimal

<!-- gh-comment-id:3324124231 --> @shahaayush1999 commented on GitHub (Sep 23, 2025): Hi @dvanmali , I've set up a minimal repro environment that you can clone and run easily. README.md has the steps for your convenience. The environment where I'm facing this bug is Tanstack Start, but this bug seems to be framework agnostic, so I used a template with hono backend + react frontend where this bug also reproduces https://github.com/shahaayush1999/check-slug-minimal
Author
Owner

@dvanmali commented on GitHub (Sep 23, 2025):

Much thanks @shahaayush1999😊 I'll see what I can do

<!-- gh-comment-id:3324414467 --> @dvanmali commented on GitHub (Sep 23, 2025): Much thanks @shahaayush1999😊 I'll see what I can do
Author
Owner

@dosubot[bot] commented on GitHub (Dec 23, 2025):

Hi, @shahaayush1999. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You reported that calling authClient.organization.checkSlug() temporarily sets useActiveOrganization().isPending to true, causing unwanted UI re-renders and blocking organization creation in Better Auth v1.3.13 with React.
  • This behavior is unintended and likely due to shared cache/state between these hooks, leading to flicker.
  • A workaround involving debouncing or ignoring isPending was suggested.
  • You provided a minimal reproduction repository as requested by the maintainer, who is currently investigating the issue.
  • The problem affects user experience and is not documented or tracked elsewhere.

Next Steps:

  • Please confirm if this issue is still relevant with the latest version of the better-auth repository by commenting here to keep the discussion open.
  • If no response is received within 7 days, I will automatically close this issue.

Thank you for your understanding and contribution!

<!-- gh-comment-id:3687183665 --> @dosubot[bot] commented on GitHub (Dec 23, 2025): Hi, @shahaayush1999. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You reported that calling `authClient.organization.checkSlug()` temporarily sets `useActiveOrganization().isPending` to true, causing unwanted UI re-renders and blocking organization creation in Better Auth v1.3.13 with React. - This behavior is unintended and likely due to shared cache/state between these hooks, leading to flicker. - A workaround involving debouncing or ignoring `isPending` was suggested. - You provided a minimal reproduction repository as requested by the maintainer, who is currently investigating the issue. - The problem affects user experience and is not documented or tracked elsewhere. **Next Steps:** - Please confirm if this issue is still relevant with the latest version of the better-auth repository by commenting here to keep the discussion open. - If no response is received within 7 days, I will automatically close this issue. Thank you for your understanding and contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10080