[GH-ISSUE #3001] Adapter Converts Null Values to String "null" for nullable Reference Fields #9429

Closed
opened 2026-04-13 04:53:30 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @0xJJW on GitHub (Jun 12, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3001

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create a field in the schema with:
    • type: "string"
    • required: false
    • references: { model: "someModel", field: "id" }
  2. Query the field using adapter.findMany()
  3. The null values are returned as the string "null"
  4. Query the same field using Kysely directly
  5. The null values are correctly returned as null

The cause of the issue appears to be here.

Current vs. Expected behavior

Expected Behaviour:

  • Null values should be returned as null, not as the string "null"
  • This should apply to all nullable fields, regardless of whether they have references

Current Behavior:

  • Null values are converted to the string "null" when using adapter.findMany()
  • This only happens for nullable string fields that have references

What version of Better Auth are you using?

1.2.7

Provide environment information

N/A

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

Backend

Auth config (if applicable)


Additional context

No response

Originally created by @0xJJW on GitHub (Jun 12, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3001 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create a field in the schema with: - type: "string" - required: false - references: { model: "someModel", field: "id" } 2. Query the field using adapter.findMany() 3. The null values are returned as the string "null" 4. Query the same field using Kysely directly 5. The null values are correctly returned as null The cause of the issue appears to be [here](https://github.com/better-auth/better-auth/blob/aedf7a36a0d6625ccad765a7dc2b15f546647dda/packages/better-auth/src/adapters/create-adapter/index.ts#L430). ### Current vs. Expected behavior Expected Behaviour: - Null values should be returned as null, not as the string "null" - This should apply to all nullable fields, regardless of whether they have references Current Behavior: - Null values are converted to the string "null" when using adapter.findMany() - This only happens for nullable string fields that have references ### What version of Better Auth are you using? 1.2.7 ### Provide environment information ```bash N/A ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-13 04:53:30 -05:00
Author
Owner

@ping-maxwell commented on GitHub (Aug 11, 2025):

Hey, can you confirm this is still an issue on latest?

<!-- gh-comment-id:3176753861 --> @ping-maxwell commented on GitHub (Aug 11, 2025): Hey, can you confirm this is still an issue on latest?
Author
Owner

@0xJJW commented on GitHub (Aug 22, 2025):

Hey @ping-maxwell,

We have tested it on 1.3.6 and it is still an issue. Looking at the source (latest) I can see there is still no null check so I am confident it still affects latest.

The issue does not impact BetterAuth core or official plugins as none appear to use nullable reference fields. For developers building custom plugins it could be an issue.

<!-- gh-comment-id:3213957502 --> @0xJJW commented on GitHub (Aug 22, 2025): Hey @ping-maxwell, We have tested it on 1.3.6 and it is still an issue. Looking at the source (latest) I can see there is still no `null` check so I am confident it still affects latest. The issue does not impact BetterAuth core or official plugins as none appear to use nullable reference fields. For developers building custom plugins it could be an issue.
Author
Owner

@ping-maxwell commented on GitHub (Aug 22, 2025):

Hey @0xJJW so this only affects ids?

<!-- gh-comment-id:3214249447 --> @ping-maxwell commented on GitHub (Aug 22, 2025): Hey @0xJJW so this only affects `id`s?
Author
Owner

@0xJJW commented on GitHub (Aug 22, 2025):

Hey @ping-maxwell

Kind of, not row id's (primary keys), rather reference id's (foreign keys).

Here is an example from one of my affected plugins.

In plugin schema we have bills and subscriptions. A bill can reference a subscription, but not all bills will have a subscription so subscriptionId is nullable.

Currently the adapter returns:

{
  subscriptionId: "null" // should be null not "null"
}
export const getPluginSchema = (options: StoreOptions) => {
  return {
    subscription: {
      fields: {
        ...
      },
    },
    bill: {
      fields: {
        ...
        subscriptionId: {
          type: "string",
          required: false, // Set required false
          references: {
            model: "subscription",
            field: "id",
            onDelete: "restrict",
          },
          fieldName: options?.schema?.bill?.fields?.subscriptionId,
        },
      },
    },
  }
};

The affected code has the comment below which is why I raised an issue without a PR. I was not sure if nullable reference fields are not supported by design. I also have some other adapter suggestions I have been meaning to collate and submit but time is very tight at the moment.

// Even if useNumberId is true, we must always return a string id output.

<!-- gh-comment-id:3215254678 --> @0xJJW commented on GitHub (Aug 22, 2025): Hey @ping-maxwell Kind of, not row id's (primary keys), rather reference id's (foreign keys). Here is an example from one of my affected plugins. In plugin schema we have bills and subscriptions. A bill can reference a subscription, but not all bills will have a subscription so subscriptionId is nullable. Currently the adapter returns: ``` { subscriptionId: "null" // should be null not "null" } ``` ``` export const getPluginSchema = (options: StoreOptions) => { return { subscription: { fields: { ... }, }, bill: { fields: { ... subscriptionId: { type: "string", required: false, // Set required false references: { model: "subscription", field: "id", onDelete: "restrict", }, fieldName: options?.schema?.bill?.fields?.subscriptionId, }, }, }, } }; ``` The affected code has the comment below which is why I raised an issue without a PR. I was not sure if nullable reference fields are not supported by design. I also have some other adapter suggestions I have been meaning to collate and submit but time is very tight at the moment. // Even if `useNumberId` is true, we must always return a string `id` output.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9429