[GH-ISSUE #3556] Incorrect FK reference for the teamMember table #9644

Closed
opened 2026-04-13 05:14:19 -05:00 by GiteaMirror · 12 comments
Owner

Originally created by @max-om on GitHub (Jul 23, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3556

Hi, with teams in organization plugin, shouldn't the teamMember have a FK reference to the memberId instead of the userId ? Logically, a user can belong to multiple organizations. But a member (org id + user id) can only belong to one org. So if a member is deleted then they should also be deleted in the teamMember table.

With the current implementation when a member is deleted, the team member is not deleted. The team member only gets deleted if the user is deleted which does not sound right logically.

Can we modify the references of default schema fields using the additional fields option or is there a way to customise the field to add references ? Currently, it looks like customising a schema feature only allows to change the name of the field and does not allow us to do anything else like what is allowed in createFieldAttribute

Originally created by @max-om on GitHub (Jul 23, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3556 Hi, with teams in organization plugin, shouldn't the teamMember have a FK reference to the memberId instead of the userId ? Logically, a user can belong to multiple organizations. But a member (org id + user id) can only belong to one org. So if a member is deleted then they should also be deleted in the teamMember table. With the current implementation when a member is deleted, the team member is not deleted. The team member only gets deleted if the user is deleted which does not sound right logically. Can we modify the references of default schema fields using the additional fields option or is there a way to customise the field to add references ? Currently, it looks like customising a schema feature only allows to change the name of the field and does not allow us to do anything else like what is allowed in createFieldAttribute
GiteaMirror added the locked label 2026-04-13 05:14:19 -05:00
Author
Owner

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

You're correct—the current teamMember table in the organization plugin uses a foreign key to userId, not memberId, which means deleting a member does not cascade to teamMember records. This can leave orphaned teamMember entries if a user remains active elsewhere. The schema customization options (like additionalFields or fields) only let you change field names or add extra fields, not alter the core foreign key structure or relationships. There isn't a built-in or documented way to change the FK reference in teamMember to memberId using the current plugin configuration options—doing so would require deeper changes at the schema and adapter level, which aren't officially supported right now citation citation.

To reply, just mention @dosu.


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

<!-- gh-comment-id:3106413470 --> @dosubot[bot] commented on GitHub (Jul 23, 2025): <!-- Answer --> You're correct—the current teamMember table in the organization plugin uses a foreign key to userId, not memberId, which means deleting a member does not cascade to teamMember records. This can leave orphaned teamMember entries if a user remains active elsewhere. The schema customization options (like additionalFields or fields) only let you change field names or add extra fields, not alter the core foreign key structure or relationships. There isn't a built-in or documented way to change the FK reference in teamMember to memberId using the current plugin configuration options—doing so would require deeper changes at the schema and adapter level, which aren't officially supported right now [citation](https://github.com/better-auth/better-auth/blob/602ab7c4c6913d601994de0ae679be6645a58d69/packages/better-auth/src/plugins/organization/schema.ts) [citation](https://github.com/better-auth/better-auth/blob/602ab7c4c6913d601994de0ae679be6645a58d69/packages/better-auth/src/plugins/organization/adapter.ts). <!-- 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/d2c61fb5-2a36-4503-80db-4bdc7f091d90?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d2c61fb5-2a36-4503-80db-4bdc7f091d90?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d2c61fb5-2a36-4503-80db-4bdc7f091d90?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d2c61fb5-2a36-4503-80db-4bdc7f091d90?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d2c61fb5-2a36-4503-80db-4bdc7f091d90?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d2c61fb5-2a36-4503-80db-4bdc7f091d90?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d2c61fb5-2a36-4503-80db-4bdc7f091d90?feedback_type=other)</sup>&nbsp;&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/3556)
Author
Owner

@max-om commented on GitHub (Jul 23, 2025):

@dosu how can I solve this issue ?

<!-- gh-comment-id:3106424108 --> @max-om commented on GitHub (Jul 23, 2025): @dosu how can I solve this issue ?
Author
Owner

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

This isn't supported out-of-the-box: the organization plugin's schema and adapter logic are tightly coupled to userId as the foreign key in teamMember, and schema customization options only let you rename fields or add extras—not change relationships or cascade rules (schema.ts, organization.ts).

If you need cascading deletes when a member is removed, you have a few options:

  • Implement manual cascading in your adapter logic: when deleting a member, also delete all teamMember records for that member's userId and organizationId. This is the most maintainable workaround and doesn't require forking the plugin (adapter.ts).
  • Use database-level triggers or constraints to enforce cascading deletes from member to teamMember, but this requires careful setup and maintenance outside of Better Auth.
  • Fork and modify the plugin to use memberId as the FK in teamMember, but this is fragile and will make upgrades harder.

If you go with a workaround, keep your custom logic isolated and document it well so you can adapt to future upstream changes.

To reply, just mention @dosu.


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

<!-- gh-comment-id:3106433340 --> @dosubot[bot] commented on GitHub (Jul 23, 2025): <!-- Answer --> This isn't supported out-of-the-box: the organization plugin's schema and adapter logic are tightly coupled to userId as the foreign key in teamMember, and schema customization options only let you rename fields or add extras—not change relationships or cascade rules ([schema.ts](https://github.com/better-auth/better-auth/blob/602ab7c4c6913d601994de0ae679be6645a58d69/packages/better-auth/src/plugins/organization/schema.ts), [organization.ts](https://github.com/better-auth/better-auth/blob/602ab7c4c6913d601994de0ae679be6645a58d69/packages/better-auth/src/plugins/organization/organization.ts)). If you need cascading deletes when a member is removed, you have a few options: - Implement manual cascading in your adapter logic: when deleting a member, also delete all teamMember records for that member's userId and organizationId. This is the most maintainable workaround and doesn't require forking the plugin ([adapter.ts](https://github.com/better-auth/better-auth/blob/602ab7c4c6913d601994de0ae679be6645a58d69/packages/better-auth/src/plugins/organization/adapter.ts)). - Use database-level triggers or constraints to enforce cascading deletes from member to teamMember, but this requires careful setup and maintenance outside of Better Auth. - Fork and modify the plugin to use memberId as the FK in teamMember, but this is fragile and will make upgrades harder. If you go with a workaround, keep your custom logic isolated and document it well so you can adapt to future upstream changes. <!-- 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/ebfcd366-39ba-4bc6-93d6-68708ff9c56a?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/ebfcd366-39ba-4bc6-93d6-68708ff9c56a?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/ebfcd366-39ba-4bc6-93d6-68708ff9c56a?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/ebfcd366-39ba-4bc6-93d6-68708ff9c56a?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/ebfcd366-39ba-4bc6-93d6-68708ff9c56a?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/ebfcd366-39ba-4bc6-93d6-68708ff9c56a?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/ebfcd366-39ba-4bc6-93d6-68708ff9c56a?feedback_type=other)</sup>&nbsp;&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/3556)
Author
Owner

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

it is already fixed. closing this.

<!-- gh-comment-id:3175267747 --> @Kinfe123 commented on GitHub (Aug 11, 2025): it is already fixed. closing this.
Author
Owner

@max-om commented on GitHub (Aug 11, 2025):

Hi @Kinfe123, this issue is not fixed.

Changes in release v1.3.5-beta.5, only adds support to referencing teamId in the team members table.

The issue here is referencing member id from the members table in the team members table instead of userId (or add additional column for member id reference).

With the proposed changes, if a member is deleted from an org, but a user still exists, the member record will be deleted from the members table but the team member record for the deleted member will still exist as the team member table references user id and org id and there is no reference to member id.

The team member will only be deleted if a team is deleted or a user is deleted

<!-- gh-comment-id:3175345216 --> @max-om commented on GitHub (Aug 11, 2025): Hi @Kinfe123, this issue is not fixed. Changes in release [v1.3.5-beta.5](https://github.com/better-auth/better-auth/releases/tag/v1.3.5-beta.5), only adds support to referencing teamId in the team members table. - https://github.com/better-auth/better-auth/pull/3801/files - https://github.com/better-auth/better-auth/pull/3833/files The issue here is referencing member id from the members table in the team members table instead of userId (or add additional column for member id reference). With the proposed changes, if a member is deleted from an org, but a user still exists, the member record will be deleted from the members table but the team member record for the deleted member will still exist as the team member table references user id and org id and there is no reference to member id. The team member will only be deleted if a team is deleted or a user is deleted
Author
Owner

@max-om commented on GitHub (Aug 11, 2025):

Can you please reopen the issue as this is not fixed. Thanks @Kinfe123

<!-- gh-comment-id:3175347634 --> @max-om commented on GitHub (Aug 11, 2025): Can you please reopen the issue as this is not fixed. Thanks @Kinfe123
Author
Owner

@dosubot[bot] commented on GitHub (Nov 10, 2025):

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

Issue Summary:

  • You raised a concern that the teamMember table should reference memberId instead of userId to enable proper cascading deletes.
  • Currently, deleting a member leaves orphaned teamMember entries due to this foreign key setup.
  • I confirmed this limitation and suggested workarounds like manual cascading deletes or database triggers.
  • Although the issue was closed by a maintainer stating it was fixed, you clarified that recent updates only added support for referencing teamId, not memberId.
  • You requested reopening the issue for a proper fix.

Next Steps:

  • Please confirm if this issue is still relevant with the latest version of better-auth by commenting here.
  • If no further activity occurs, this issue will be automatically closed in 7 days.

Thank you for your understanding and contribution!

<!-- gh-comment-id:3512648689 --> @dosubot[bot] commented on GitHub (Nov 10, 2025): Hi, @max-om. 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 raised a concern that the `teamMember` table should reference `memberId` instead of `userId` to enable proper cascading deletes. - Currently, deleting a member leaves orphaned `teamMember` entries due to this foreign key setup. - I confirmed this limitation and suggested workarounds like manual cascading deletes or database triggers. - Although the issue was closed by a maintainer stating it was fixed, you clarified that recent updates only added support for referencing `teamId`, not `memberId`. - You requested reopening the issue for a proper fix. **Next Steps:** - Please confirm if this issue is still relevant with the latest version of better-auth by commenting here. - If no further activity occurs, this issue will be automatically closed in 7 days. Thank you for your understanding and contribution!
Author
Owner

@max-om commented on GitHub (Nov 17, 2025):

Hi @dosu, yes it is still relevant

<!-- gh-comment-id:3540076059 --> @max-om commented on GitHub (Nov 17, 2025): Hi @dosu, yes it is still relevant
Author
Owner

@max-om commented on GitHub (Nov 17, 2025):

The fix here only fixes the implementation programmatically using the better auth API but I believe this is more of a logical design of a memberId FK reference with cascade delete in the team members table: https://github.com/better-auth/better-auth/pull/5063/files

<!-- gh-comment-id:3540089079 --> @max-om commented on GitHub (Nov 17, 2025): The fix here only fixes the implementation programmatically using the better auth API but I believe this is more of a logical design of a memberId FK reference with cascade delete in the team members table: https://github.com/better-auth/better-auth/pull/5063/files
Author
Owner

@dosubot[bot] commented on GitHub (Nov 17, 2025):

Thanks for confirming. The issue is still unresolved: the teamMember table continues to use userId as its foreign key, not memberId, and this isn't configurable through current schema customization options. Recent changes (like v1.3.5-beta.5 and related PRs) only added or fixed the teamId reference, not the core problem of referencing memberId instead of userId. As a result, deleting a member does not cascade to teamMember records, which can leave orphaned entries if the user remains active elsewhere. There are no built-in or documented ways to change this relationship—addressing it would require manual adapter logic, database triggers, or forking the plugin, all of which come with maintenance risks and are not officially supported right now.

If you need a workaround, manual cascading deletes in your adapter logic or database-level triggers are the most practical options until deeper schema customization is supported.

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:3540096204 --> @dosubot[bot] commented on GitHub (Nov 17, 2025): <!-- Answer --> Thanks for confirming. The issue is still unresolved: the teamMember table continues to use userId as its foreign key, not memberId, and this isn't configurable through current schema customization options. Recent changes (like v1.3.5-beta.5 and related PRs) only added or fixed the teamId reference, not the core problem of referencing memberId instead of userId. As a result, deleting a member does not cascade to teamMember records, which can leave orphaned entries if the user remains active elsewhere. There are no built-in or documented ways to change this relationship—addressing it would require manual adapter logic, database triggers, or forking the plugin, all of which come with maintenance risks and are not officially supported right now. If you need a workaround, manual cascading deletes in your adapter logic or database-level triggers are the most practical options until deeper schema customization is supported. <!-- 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/fc69ecbf-a32d-42cb-ad0b-5000db615298?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/fc69ecbf-a32d-42cb-ad0b-5000db615298?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/fc69ecbf-a32d-42cb-ad0b-5000db615298?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/fc69ecbf-a32d-42cb-ad0b-5000db615298?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/fc69ecbf-a32d-42cb-ad0b-5000db615298?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/fc69ecbf-a32d-42cb-ad0b-5000db615298?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/fc69ecbf-a32d-42cb-ad0b-5000db615298?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/3556)
Author
Owner

@max-om commented on GitHub (Nov 17, 2025):

@dosu, yes, I have implemented a custom logic at the moment...but is there an option for additional fields for the team members table similar to other tables so that we can modify schema to configure additional fields ?

<!-- gh-comment-id:3540105124 --> @max-om commented on GitHub (Nov 17, 2025): @dosu, yes, I have implemented a custom logic at the moment...but is there an option for additional fields for the team members table similar to other tables so that we can modify schema to configure additional fields ?
Author
Owner

@dosubot[bot] commented on GitHub (Nov 17, 2025):

No, the teamMember table does not support adding additional fields via schema customization—unlike other organization tables, it lacks an additionalFields option in the plugin configuration. You can only rename existing fields for teamMember, not add new ones through the standard config. If you need extra columns, you’d have to extend the schema manually or modify the adapter, but this isn’t officially supported and could complicate upgrades. For reference, see the schema config structure and limitations here.

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:3540109138 --> @dosubot[bot] commented on GitHub (Nov 17, 2025): <!-- Answer --> No, the teamMember table does not support adding additional fields via schema customization—unlike other organization tables, it lacks an `additionalFields` option in the plugin configuration. You can only rename existing fields for teamMember, not add new ones through the standard config. If you need extra columns, you’d have to extend the schema manually or modify the adapter, but this isn’t officially supported and could complicate upgrades. For reference, see the schema config structure and limitations [here](https://github.com/better-auth/better-auth/blob/d768852258d1fea921984196806608af2983a867/packages/better-auth/src/plugins/organization/types.ts#L248-L306). <!-- 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/4bf9c415-3ed6-4e11-b4c0-c1c49160bd93?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/4bf9c415-3ed6-4e11-b4c0-c1c49160bd93?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/4bf9c415-3ed6-4e11-b4c0-c1c49160bd93?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/4bf9c415-3ed6-4e11-b4c0-c1c49160bd93?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/4bf9c415-3ed6-4e11-b4c0-c1c49160bd93?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/4bf9c415-3ed6-4e11-b4c0-c1c49160bd93?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/4bf9c415-3ed6-4e11-b4c0-c1c49160bd93?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/3556)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9644