[GH-ISSUE #1643] Two members created when an organization is created with defaultTeam enabled #26171

Closed
opened 2026-04-17 16:39:11 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @sikula on GitHub (Mar 2, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/1643

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Enable the organization plugin with like so:
export const auth = betterAuth({
  database: drizzleAdapter(db, {
      provider: "pg",
      usePlural: true,
    }),
   emailAndPassword: {
      enabled: true,
    },
    plugins: [
      organization({
        teams: {
          enabled: true,
          defaultTeam: {
            enabled: true
          }
        }
      })
    ]
})
  1. Create an organization
  2. Check the members table, two entries are created on where the teamId is null and the other where the teamId is populated, the entries are created within milliseconds of each other

Current vs. Expected behavior

Currently, two entries in the members table are created when the expectation is that 1 member is created with the teamId populated

What version of Better Auth are you using?

1.2.1

Provide environment information

- OS: Mac
- Browser: Brave
- Framework: remix
- Database: Postgres + Drizzle Adapter

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
    usePlural: true,
  }),
  emailAndPassword: {
    enabled: true,
  },
  plugins: [
    username(),
    organization({
      async sendInvitationEmail(data) {
        console.log("Invite", data.id, data);
      },
      teams: {
        enabled: true,
        defaultTeam: {
          enabled: true,
        },
      },
    }),
    passkey({
      advanced: {
        webAuthnChallengeCookie: "passkey",
      },
    }),
    customSession(async ({ user, session }) => {
      const { activeOrganizationSlug } = await getActiveOrganizationId(
        session.userId
      );

      return {
        session: {
          ...session,
          activeOrganizationSlug,
        },
        user: {
          ...user,
        },
      };
    }),
  ],
  databaseHooks: {
    session: {
      create: {
        before: async (session) => {
          const { activeOrganizationId } = await getActiveOrganizationId(
            session.userId
          );

          return {
            data: {
              ...session,
              activeOrganizationId,
            },
          };
        },
      },
    },
  },
});

Additional context

I tested against version 1.2.0, and 1.2.1. The drizzle query logs show an organization being created, then a member being created, then a team being created, then a member being created. I checked my logic for anything that would create an additional member and there wasn't anything

Originally created by @sikula on GitHub (Mar 2, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/1643 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Enable the organization plugin with like so: ```javascript export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", usePlural: true, }), emailAndPassword: { enabled: true, }, plugins: [ organization({ teams: { enabled: true, defaultTeam: { enabled: true } } }) ] }) ``` 2. Create an organization 3. Check the members table, two entries are created on where the teamId is null and the other where the teamId is populated, the entries are created within milliseconds of each other ### Current vs. Expected behavior Currently, two entries in the members table are created when the expectation is that 1 member is created with the teamId populated ### What version of Better Auth are you using? 1.2.1 ### Provide environment information ```bash - OS: Mac - Browser: Brave - Framework: remix - Database: Postgres + Drizzle Adapter ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", usePlural: true, }), emailAndPassword: { enabled: true, }, plugins: [ username(), organization({ async sendInvitationEmail(data) { console.log("Invite", data.id, data); }, teams: { enabled: true, defaultTeam: { enabled: true, }, }, }), passkey({ advanced: { webAuthnChallengeCookie: "passkey", }, }), customSession(async ({ user, session }) => { const { activeOrganizationSlug } = await getActiveOrganizationId( session.userId ); return { session: { ...session, activeOrganizationSlug, }, user: { ...user, }, }; }), ], databaseHooks: { session: { create: { before: async (session) => { const { activeOrganizationId } = await getActiveOrganizationId( session.userId ); return { data: { ...session, activeOrganizationId, }, }; }, }, }, }, }); ``` ### Additional context I tested against version 1.2.0, and 1.2.1. The drizzle query logs show an organization being created, then a member being created, then a team being created, then a member being created. I checked my logic for anything that would create an additional member and there wasn't anything
GiteaMirror added the lockedbug labels 2026-04-17 16:39:11 -05:00
Author
Owner

@sikula commented on GitHub (Mar 2, 2025):

@Bekacru Thank you very much! You guys are absolutely amazing :) !!

<!-- gh-comment-id:2692882013 --> @sikula commented on GitHub (Mar 2, 2025): @Bekacru Thank you very much! You guys are absolutely amazing :) !!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#26171