[GH-ISSUE #3883] Bug: "User is not a member" error when using organization.setActive with organizationSlug (works with organizationId) #9754

Closed
opened 2026-04-13 05:26:59 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @joaoliveirapb on GitHub (Aug 8, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3883

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Set up better-auth with the organization plugin.
  2. Create a user and multiple organizations where the user is a member.
  3. Call setActive with organizationSlug: "my-slug" — it fails with "user is not a member" error.
  4. Call setActive with organizationId: "actual-id" — it succeeds.

Example code:

const response = await authClient.organization.setActive({
  organizationSlug: "my-workspace-slug",
});

Current vs. Expected behavior

The method should resolve the organization by slug, verify membership correctly, and set it as active without errors, as it did in v1.2.10.

What version of Better Auth are you using?

1.3.4

Provide environment information

- OS: Windowns 11
- Browser: Chorme

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

Client

Auth config (if applicable)

BACKEND:

import { betterAuth } from 'better-auth'
import { drizzleAdapter } from 'better-auth/adapters/drizzle'
import { magicLink, organization } from 'better-auth/plugins'
import { db } from '../db/connection'
import * as schema from '../db/schema/auth-schema'
import { env } from '../env'
import { customOrganizationUpdatePlugin } from '../plugins/custom-organization-update'

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: 'pg',
    schema,
    usePlural: true,
  }),
  secret: env.BETTER_AUTH_SECRET,
  baseURL: env.BETTER_AUTH_URL,
  advanced: {
    crossSubDomainCookies: {
      enabled: true,
      domain: env.DOMAIN,
    },
  },
  trustedOrigins: [env.CLIENT_APP_BASE_URL],
  plugins: [
    magicLink({
      sendMagicLink: async ({ email, url, token }) => {
        const emailService = new EmailService()
        await emailService.sendMagicLinkEmail(email, url, token)
      },
    }),
    organization({
      sendInvitationEmail: async (data, _request) => {
        const emailService = new EmailService()
        await emailService.sendOrganizationInvitationEmail(data.email, data.id)
      },
    }),
    customOrganizationUpdatePlugin(),
  ],
  socialProviders: {
    google: {
      clientId: env.GOOGLE_CLIENT_ID,
      clientSecret: env.GOOGLE_CLIENT_SECRET,
    },
  },
})

FRONTEND:

import { magicLinkClient, organizationClient } from 'better-auth/client/plugins'
import { createAuthClient } from 'better-auth/react'
import { env } from '../env'

export const authClient = createAuthClient({
  baseURL: env.VITE_API_BASE_URL,
  fetchOptions: { credentials: 'include' },
  plugins: [magicLinkClient(), organizationClient()],
})

Additional context

The organization appears in organization.list(), confirming membership.

Originally created by @joaoliveirapb on GitHub (Aug 8, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3883 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Set up better-auth with the organization plugin. 2. Create a user and multiple organizations where the user is a member. 3. Call `setActive` with `organizationSlug: "my-slug"` — it fails with "user is not a member" error. 4. Call `setActive` with `organizationId: "actual-id"` — it succeeds. Example code: ```typescript const response = await authClient.organization.setActive({ organizationSlug: "my-workspace-slug", }); ``` ### Current vs. Expected behavior The method should resolve the organization by slug, verify membership correctly, and set it as active without errors, as it did in v1.2.10. ### What version of Better Auth are you using? 1.3.4 ### Provide environment information ```bash - OS: Windowns 11 - Browser: Chorme ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript BACKEND: import { betterAuth } from 'better-auth' import { drizzleAdapter } from 'better-auth/adapters/drizzle' import { magicLink, organization } from 'better-auth/plugins' import { db } from '../db/connection' import * as schema from '../db/schema/auth-schema' import { env } from '../env' import { customOrganizationUpdatePlugin } from '../plugins/custom-organization-update' export const auth = betterAuth({ database: drizzleAdapter(db, { provider: 'pg', schema, usePlural: true, }), secret: env.BETTER_AUTH_SECRET, baseURL: env.BETTER_AUTH_URL, advanced: { crossSubDomainCookies: { enabled: true, domain: env.DOMAIN, }, }, trustedOrigins: [env.CLIENT_APP_BASE_URL], plugins: [ magicLink({ sendMagicLink: async ({ email, url, token }) => { const emailService = new EmailService() await emailService.sendMagicLinkEmail(email, url, token) }, }), organization({ sendInvitationEmail: async (data, _request) => { const emailService = new EmailService() await emailService.sendOrganizationInvitationEmail(data.email, data.id) }, }), customOrganizationUpdatePlugin(), ], socialProviders: { google: { clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, }, }, }) FRONTEND: import { magicLinkClient, organizationClient } from 'better-auth/client/plugins' import { createAuthClient } from 'better-auth/react' import { env } from '../env' export const authClient = createAuthClient({ baseURL: env.VITE_API_BASE_URL, fetchOptions: { credentials: 'include' }, plugins: [magicLinkClient(), organizationClient()], }) ``` ### Additional context The organization appears in `organization.list()`, confirming membership.
GiteaMirror added the lockedbug labels 2026-04-13 05:26:59 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 8, 2025):

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

This is a confirmed regression in Better Auth v1.3.2–v1.3.4: calling organization.setActive with organizationSlug fails with a "user is not a member" error, even though it works with organizationId and worked in v1.2.10. The bug was introduced by a change that only checked membership using the organization ID, without resolving slugs to IDs internally. This is tracked in issues like #3528 and #3589.

A fix was merged in PR #3757 (2025-08-03): the code now resolves organizationSlug to organizationId before checking membership, so both methods work as expected.

To work around this in v1.3.4, manually resolve the slug to an ID (e.g., fetch the org by slug, then call setActive with the ID). Upgrading to a version after PR #3757 is the recommended fix. Rolling back to v1.3.1 also restores the old behavior, but upgrading is preferred for long-term stability.

References:
#3528
#3589
PR #3757

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:3168397327 --> @dosubot[bot] commented on GitHub (Aug 8, 2025): <!-- Greeting --> Hi @joaoliveirapb! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a confirmed regression in Better Auth v1.3.2–v1.3.4: calling `organization.setActive` with `organizationSlug` fails with a "user is not a member" error, even though it works with `organizationId` and worked in v1.2.10. The bug was introduced by a change that only checked membership using the organization ID, without resolving slugs to IDs internally. This is tracked in issues like [#3528](https://github.com/better-auth/better-auth/issues/3528) and [#3589](https://github.com/better-auth/better-auth/issues/3589). A fix was merged in [PR #3757](https://github.com/better-auth/better-auth/pull/3757) (2025-08-03): the code now resolves `organizationSlug` to `organizationId` before checking membership, so both methods work as expected. To work around this in v1.3.4, manually resolve the slug to an ID (e.g., fetch the org by slug, then call `setActive` with the ID). Upgrading to a version after PR #3757 is the recommended fix. Rolling back to v1.3.1 also restores the old behavior, but upgrading is preferred for long-term stability. References: [#3528](https://github.com/better-auth/better-auth/issues/3528) [#3589](https://github.com/better-auth/better-auth/issues/3589) [PR #3757](https://github.com/better-auth/better-auth/pull/3757) <!-- 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/f3f2e3e7-ce59-417d-8d12-8ee92d9ed54a?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/f3f2e3e7-ce59-417d-8d12-8ee92d9ed54a?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/f3f2e3e7-ce59-417d-8d12-8ee92d9ed54a?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/f3f2e3e7-ce59-417d-8d12-8ee92d9ed54a?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/f3f2e3e7-ce59-417d-8d12-8ee92d9ed54a?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/f3f2e3e7-ce59-417d-8d12-8ee92d9ed54a?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/f3f2e3e7-ce59-417d-8d12-8ee92d9ed54a?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/3883)
Author
Owner

@Kinfe123 commented on GitHub (Aug 8, 2025):

closing via - #3757 please update to latest if so and should be fixed.

<!-- gh-comment-id:3168687271 --> @Kinfe123 commented on GitHub (Aug 8, 2025): closing via - #3757 please update to latest if so and should be fixed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9754