Extended schema fields not being inferred by TS nor included on the returned response #682

Closed
opened 2026-03-13 08:00:09 -05:00 by GiteaMirror · 17 comments
Owner

Originally created by @SiNONiMiTY on GitHub (Feb 16, 2025).

Originally assigned to: @bytaesu on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Just initialize an auth() object with additional user fields

Current vs. Expected behavior

Greetings!

I have hit an issue wherein i'm trying to extend the core user schema by following the documentation

Image

Image

As you can see here, the additional fields that was declared on the auth object is not inferred by TS
Also performing console.log(noExtendedFields), the declared fields are also not present

What version of Better Auth are you using?

v1.1.18

Provide environment information

Windows 11

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
    user: {
        additionalFields: {
            roleId: {
                type: 'string',
                required: false,
                defaultValue: 'ROLE_001',
                input: false,
            },
            merchantId: {
                type: 'string',
                required: false,
                defaultValue: 'MERCHANT_001',
                input: false,
            },
            isLocked: {
                type: 'boolean',
                required: false,
                defaultValue: false,
                input: false,
            },
        },
    },
});

Additional context

No response

Originally created by @SiNONiMiTY on GitHub (Feb 16, 2025). Originally assigned to: @bytaesu on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Just initialize an auth() object with additional user fields ### Current vs. Expected behavior Greetings! I have hit an issue wherein i'm trying to extend the core user schema by following the documentation ![Image](https://github.com/user-attachments/assets/3a6d5dd2-2168-497a-b4e3-99f3f87e3862) ![Image](https://github.com/user-attachments/assets/cd4a7345-6123-4677-a15c-2b909a3c6ef7) As you can see here, the additional fields that was declared on the auth object is not inferred by TS Also performing `console.log(noExtendedFields)`, the declared fields are also not present ### What version of Better Auth are you using? v1.1.18 ### Provide environment information ```bash Windows 11 ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ user: { additionalFields: { roleId: { type: 'string', required: false, defaultValue: 'ROLE_001', input: false, }, merchantId: { type: 'string', required: false, defaultValue: 'MERCHANT_001', input: false, }, isLocked: { type: 'boolean', required: false, defaultValue: false, input: false, }, }, }, }); ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-03-13 08:00:09 -05:00
Author
Owner

@iamalexm commented on GitHub (Feb 21, 2025):

Hi,

What you did is correct, but you need a couple more configuration. I juste had the same issue and here is how I managed to make it works :

  1. You need to update your schema and push it to your database
file : schema.ts
export const user = pgTable("user", {
...
...
roleId: text("role_id"),
merchandId: text("mechant_id"),
isLocked: boolean("is_locked"),
});
  1. Then infer your auth-client.ts
file: auth-client.ts
import { inferAdditionalFields } from "better-auth/client/plugins";
 
export const authClient = createAuthClient({
  plugins: [inferAdditionalFields({
      user: {
        roleId: {
          type: "string"
        },
merchandId: {
          type: "string"
        },
isLocked: {
          type: "boolean"
        }
      }
  })],
});
  1. Then you should be able to use updateUser to modifiy you database
await authClient.updateUser(
      {
        name: 'John Doe',
        roleId: 123, <--- additional field
        isLocked: true, <--- additional field
      })

Hope it helps,

Alex

@iamalexm commented on GitHub (Feb 21, 2025): Hi, What you did is correct, but you need a couple more configuration. I juste had the same issue and here is how I managed to make it works : 1. You need to update your schema and push it to your database ```c file : schema.ts export const user = pgTable("user", { ... ... roleId: text("role_id"), merchandId: text("mechant_id"), isLocked: boolean("is_locked"), }); ``` 2. Then infer your auth-client.ts ```c file: auth-client.ts import { inferAdditionalFields } from "better-auth/client/plugins"; export const authClient = createAuthClient({ plugins: [inferAdditionalFields({ user: { roleId: { type: "string" }, merchandId: { type: "string" }, isLocked: { type: "boolean" } } })], }); ``` 3. Then you should be able to use `updateUser` to modifiy you database ```c await authClient.updateUser( { name: 'John Doe', roleId: 123, <--- additional field isLocked: true, <--- additional field }) ``` Hope it helps, Alex
Author
Owner

@SiNONiMiTY commented on GitHub (Feb 22, 2025):

@iamalexm thanks for the insight, but I am currently using it on the server side, hence the call to the .api() method.

After signing in, it doesn't make sense to do another call to the getSession() method just to retrieve the custom fields.

Those custom fields should already be included on other methods that return the user and session objects

@SiNONiMiTY commented on GitHub (Feb 22, 2025): @iamalexm thanks for the insight, but I am currently using it on the server side, hence the call to the .api() method. After signing in, it doesn't make sense to do another call to the getSession() method just to retrieve the custom fields. Those custom fields should already be included on other methods that return the `user` and `session` objects
Author
Owner

@vanshavenger commented on GitHub (Mar 8, 2025):

Is it resolved, getting this error on both server and client side

@vanshavenger commented on GitHub (Mar 8, 2025): Is it resolved, getting this error on both server and client side
Author
Owner

@lucasferreiralsf commented on GitHub (Mar 16, 2025):

I'm getting this error on the server also (Inside the sendResetPassword and sendVerificationEmail), the additional fields is not inferring automatically as said on the docs.

Image

@lucasferreiralsf commented on GitHub (Mar 16, 2025): I'm getting this error on the server also (Inside the `sendResetPassword` and `sendVerificationEmail`), the additional fields is not inferring automatically as said on the docs. ![Image](https://github.com/user-attachments/assets/c63c0955-9067-4d60-9ec0-43cffe8f0b78)
Author
Owner

@kawpii commented on GitHub (Mar 21, 2025):

Experiencing the same

Server : src/lib/auth.ts

import Database from 'better-sqlite3'

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    autoSignIn: false,
  },
  database: new Database('database.db'),
  plugins: [
    username(),
  ],
  user: {
    additionalFields: {
      userRole: {
        type: 'string',
        required: true,
      },
      branchId: {
        type: 'number',
        required: true,
      },
    },
  },

})

Client : src/lib/auth-client.ts

import { createAuthClient } from 'better-auth/client'
import {
  inferAdditionalFields,
  usernameClient,
} from 'better-auth/client/plugins'

export const authClient = createAuthClient({
  baseURL: 'http://localhost:4000', // the base url of your auth server
  plugins: [
    usernameClient(),
    inferAdditionalFields({
      user: {
        userRole: {
          type: 'string',
        },
        branchId: {
          type: 'number',
        },
      },
    }),
  ],
})

Response

{
    "token": null,
    "user": {
        "id": "VSM3jMXVAv8OTzOYgQNZgaUS1nyTNL7E",
        "email": "test@gmail.com",
        "name": "test",
        "image": null,
        "emailVerified": false,
        "createdAt": "2025-03-21T15:37:12.777Z",
        "updatedAt": "2025-03-21T15:37:12.777Z"
    }
}

Version:

"better-auth": "^1.2.4",

@kawpii commented on GitHub (Mar 21, 2025): Experiencing the same Server : src/lib/`auth.ts` ``` import Database from 'better-sqlite3' export const auth = betterAuth({ emailAndPassword: { enabled: true, autoSignIn: false, }, database: new Database('database.db'), plugins: [ username(), ], user: { additionalFields: { userRole: { type: 'string', required: true, }, branchId: { type: 'number', required: true, }, }, }, }) ``` Client : src/lib/`auth-client.ts` ``` import { createAuthClient } from 'better-auth/client' import { inferAdditionalFields, usernameClient, } from 'better-auth/client/plugins' export const authClient = createAuthClient({ baseURL: 'http://localhost:4000', // the base url of your auth server plugins: [ usernameClient(), inferAdditionalFields({ user: { userRole: { type: 'string', }, branchId: { type: 'number', }, }, }), ], }) ``` Response ``` { "token": null, "user": { "id": "VSM3jMXVAv8OTzOYgQNZgaUS1nyTNL7E", "email": "test@gmail.com", "name": "test", "image": null, "emailVerified": false, "createdAt": "2025-03-21T15:37:12.777Z", "updatedAt": "2025-03-21T15:37:12.777Z" } } ``` Version: "better-auth": "^1.2.4",
Author
Owner

@mrctrifork commented on GitHub (Mar 30, 2025):

I am experiencing the same using better-auth 1.2.5

@mrctrifork commented on GitHub (Mar 30, 2025): I am experiencing the same using better-auth 1.2.5
Author
Owner

@Scholar01 commented on GitHub (Apr 7, 2025):

+1

@Scholar01 commented on GitHub (Apr 7, 2025): +1
Author
Owner

@mfazail commented on GitHub (May 3, 2025):

Same issue

Added extra field

Image

Infer types from auth

Image

But not getting types on update user or even in customSchema plugin

Image

Extra field is getting undefined response

Image

@mfazail commented on GitHub (May 3, 2025): Same issue ## Added extra field ![Image](https://github.com/user-attachments/assets/1a647b02-f57f-4cac-8ac7-b6baf6f34e4a) ## Infer types from auth ![Image](https://github.com/user-attachments/assets/f0634341-4d7f-444a-9996-47684a096fb6) ## But not getting types on update user or even in customSchema plugin ![Image](https://github.com/user-attachments/assets/56bff0ce-6af1-462e-9496-253af93be8f4) ## Extra field is getting undefined response ![Image](https://github.com/user-attachments/assets/8aebf987-937f-46e6-8849-6fa0988869d5)
Author
Owner

@pranavp10 commented on GitHub (May 18, 2025):

Event it's not working for me as well

`
import {
organizationClient,
adminClient,
apiKeyClient,
inferAdditionalFields,
} from 'better-auth/client/plugins';
import { createAuthClient as createBetterAuthClient } from 'better-auth/react';

export const createAuthClient = ({ apiBaseUrl }: { apiBaseUrl: string }) =>
createBetterAuthClient({
baseURL: apiBaseUrl,
plugins: [
organizationClient(),
adminClient(),
apiKeyClient(),
inferAdditionalFields({
user: {
activeOrganization: {
type: 'string',
},
activeMode: {
type: 'string',
},
},
}),
],
});
`

@pranavp10 commented on GitHub (May 18, 2025): Event it's not working for me as well ` import { organizationClient, adminClient, apiKeyClient, inferAdditionalFields, } from 'better-auth/client/plugins'; import { createAuthClient as createBetterAuthClient } from 'better-auth/react'; export const createAuthClient = ({ apiBaseUrl }: { apiBaseUrl: string }) => createBetterAuthClient({ baseURL: apiBaseUrl, plugins: [ organizationClient(), adminClient(), apiKeyClient(), inferAdditionalFields({ user: { activeOrganization: { type: 'string', }, activeMode: { type: 'string', }, }, }), ], }); `
Author
Owner

@Scholar01 commented on GitHub (May 27, 2025):

I solved this problem. I found out that fieldName affects parsing, so it can be included in the return without setting fieldName.

@Scholar01 commented on GitHub (May 27, 2025): I solved this problem. I found out that fieldName affects parsing, so it can be included in the return without setting fieldName.
Author
Owner

@mfazail commented on GitHub (May 27, 2025):

I solved this problem. I found out that fieldName affects parsing, so it can be included in the return without setting fieldName.

Ok will give it try 👍🏻

@mfazail commented on GitHub (May 27, 2025): > I solved this problem. I found out that fieldName affects parsing, so it can be included in the return without setting fieldName. Ok will give it try 👍🏻
Author
Owner

@eldiren commented on GitHub (May 31, 2025):

I solved this problem. I found out that fieldName affects parsing, so it can be included in the return without setting fieldName.

Can you explain this solution better, because for me for me on return from signUpEmail, signInEmail, or signInUsername I'm not getting my defined fields on the server. Also the op isn't using fieldName in their schema definition, and neither am I:
user: { modelName: "users", additionalFields: { profileimg: { type: "string" }, roles: { type: "number[]", defaultValue: [], input: false } } }

@eldiren commented on GitHub (May 31, 2025): > I solved this problem. I found out that fieldName affects parsing, so it can be included in the return without setting fieldName. Can you explain this solution better, because for me for me on return from signUpEmail, signInEmail, or signInUsername I'm not getting my defined fields on the server. Also the op isn't using fieldName in their schema definition, and neither am I: ` user: { modelName: "users", additionalFields: { profileimg: { type: "string" }, roles: { type: "number[]", defaultValue: [], input: false } } } `
Author
Owner

@maelp commented on GitHub (Aug 25, 2025):

I also have issues with the fields config? isn't that meant to rename fields in the typescript code? or it's just for the postgres names?

    fields: {
      emailVerified: "email_verified",
      createdAt: "created_at",
      updatedAt: "updated_at",
    },

I wanted to have snake-cased names everywhere...

@maelp commented on GitHub (Aug 25, 2025): I also have issues with the `fields` config? isn't that meant to rename fields in the typescript code? or it's just for the postgres names? ``` fields: { emailVerified: "email_verified", createdAt: "created_at", updatedAt: "updated_at", }, ``` I wanted to have snake-cased names everywhere...
Author
Owner

@maulik13 commented on GitHub (Aug 30, 2025):

One more user here struggling with this one. We do calls to better-auth apis on the server side and I do not see any way to get proper type-safety for having additional fields on the response side. The body handles them well since there is provision for it in the code.

For example using auth.api.signUpEmail does not return user with additional fields that I have defined in my options.

The reason seems the hardcoded response in file,
https://github.com/better-auth/better-auth/blob/v1.3.8-beta.7/packages/better-auth/src/api/routes/sign-up.ts#L312-L321

@maulik13 commented on GitHub (Aug 30, 2025): One more user here struggling with this one. We do calls to better-auth apis on the server side and I do not see any way to get proper type-safety for having additional fields on the response side. The body handles them well since there is provision for it in the code. For example using `auth.api.signUpEmail` does not return user with additional fields that I have defined in my options. The reason seems the hardcoded response in file, https://github.com/better-auth/better-auth/blob/v1.3.8-beta.7/packages/better-auth/src/api/routes/sign-up.ts#L312-L321
Author
Owner

@jarvis394 commented on GitHub (Nov 25, 2025):

https://github.com/better-auth/better-auth/pull/3368

Waiting for this to get merged

@jarvis394 commented on GitHub (Nov 25, 2025): https://github.com/better-auth/better-auth/pull/3368 Waiting for this to get merged
Author
Owner

@bytaesu commented on GitHub (Jan 15, 2026):

I'm checking this 🙂

@bytaesu commented on GitHub (Jan 15, 2026): I'm checking this 🙂
Author
Owner

@bytaesu commented on GitHub (Jan 16, 2026):

Hello!

This issue seems already been resolved with the schema parsers. However, I created a PR to make the handling more centralized and added regression test cases there.

That said, Better Auth still has a limitation where additionalFields are not fully inferred within plugin endpoints and callback hooks.

Don't worry 😊

This is not an issue at runtime, but I’ll look into possible solutions by passing types through to plugins at the type-level in the future.

@bytaesu commented on GitHub (Jan 16, 2026): Hello! This issue seems already been resolved with the schema parsers. However, I created a PR to make the handling more centralized and added regression test cases there. That said, Better Auth still has a limitation where additionalFields are not fully inferred within plugin endpoints and callback hooks. Don't worry 😊 This is not an issue at runtime, but I’ll look into possible solutions by passing types through to plugins at the type-level in the future.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#682