[GH-ISSUE #6239] typeof auth.$Infer.Session don't include additionalFields #19087

Closed
opened 2026-04-15 17:52:40 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @eloi24 on GitHub (Nov 23, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/6239

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

export type UserSession = typeof auth.$Infer.Session

additionalFields aren't added to the type

Current vs. Expected behavior

The session object doesn't contain the additional fields for the user object

What version of Better Auth are you using?

1.4.1

System info

{
  "system": {
    "platform": "win32",
    "arch": "x64",
    "version": "Windows 11 Pro",
    "release": "10.0.26200",
    "cpuCount": 12,
    "cpuModel": "AMD Ryzen 5 2600X Six-Core Processor           ",
    "totalMemory": "15.93 GB",
    "freeMemory": "5.64 GB"
  },
  "node": {
    "version": "v22.16.0",
    "env": "development"
  },
  "packageManager": {
    "name": "bun",
    "version": "1.3.2"
  },
  "frameworks": null,
  "databases": [
    {
      "name": "drizzle",
      "version": "0.44.7"
    }
  ],
  "betterAuth": {
    "version": "1.4.1",
    "config": null
  }

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

Types

Auth config (if applicable)

export const authConfig = {
  plugins: [
    customSession(async ({ user, session }) => {
      return {
        user,
        session
      }
    }),
    organization({
      requireEmailVerificationOnInvitation: true,
      teams: {
        enabled: true,
        allowRemovingAllTeams: false
      },
      schema: {
        organization: {
          additionalFields: {
            country: {
              type: 'string',
              required: true
            }
          }
        }
      }
    }),
    stripe({
      stripeClient,
      stripeWebhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
      subscription: {
        enabled: true,
        plans: [{ name: 'Test' }]
      }
    }),
    lastLoginMethod({
      maxAge: 60 * 60 * 24 * 30 // Default: 30 days in seconds
    }),
    emailOTP({
      async sendVerificationOTP({ otp, type }) {}
    })
  ],
  emailAndPassword: {
    enabled: true,
    minPasswordLength: 8
  },
  user: {
    additionalFields: {
      surname: {
        type: 'string',
        required: false,
        input: true
      },
      measuramentSystem: {
        type: 'string',
        required: false,
        input: false
      },
      language: {
        type: 'string',
        required: false,
        input: false
      },
      country: {
        type: 'string',
        required: false,
        input: false
      },
      timezone: {
        type: 'string',
        required: false,
        input: false
      },
      initialized: {
        type: 'boolean',
        required: false,
        input: false,
        defaultValue: false
      },
      lastUsedOrganizationId: {
        type: 'string',
        required: false,
        input: false
      }
    },
    fields: {}
  }
} satisfies BetterAuthOptions

const auth = betterAuth(authConfig)

export type UserSession = typeof auth.$Infer.Session

Additional context

No response

Originally created by @eloi24 on GitHub (Nov 23, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/6239 ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce export type UserSession = typeof auth.$Infer.Session additionalFields aren't added to the type ### Current vs. Expected behavior The session object doesn't contain the additional fields for the user object ### What version of Better Auth are you using? 1.4.1 ### System info ```bash { "system": { "platform": "win32", "arch": "x64", "version": "Windows 11 Pro", "release": "10.0.26200", "cpuCount": 12, "cpuModel": "AMD Ryzen 5 2600X Six-Core Processor ", "totalMemory": "15.93 GB", "freeMemory": "5.64 GB" }, "node": { "version": "v22.16.0", "env": "development" }, "packageManager": { "name": "bun", "version": "1.3.2" }, "frameworks": null, "databases": [ { "name": "drizzle", "version": "0.44.7" } ], "betterAuth": { "version": "1.4.1", "config": null } ``` ### Which area(s) are affected? (Select all that apply) Types ### Auth config (if applicable) ```typescript export const authConfig = { plugins: [ customSession(async ({ user, session }) => { return { user, session } }), organization({ requireEmailVerificationOnInvitation: true, teams: { enabled: true, allowRemovingAllTeams: false }, schema: { organization: { additionalFields: { country: { type: 'string', required: true } } } } }), stripe({ stripeClient, stripeWebhookSecret: process.env.STRIPE_WEBHOOK_SECRET!, subscription: { enabled: true, plans: [{ name: 'Test' }] } }), lastLoginMethod({ maxAge: 60 * 60 * 24 * 30 // Default: 30 days in seconds }), emailOTP({ async sendVerificationOTP({ otp, type }) {} }) ], emailAndPassword: { enabled: true, minPasswordLength: 8 }, user: { additionalFields: { surname: { type: 'string', required: false, input: true }, measuramentSystem: { type: 'string', required: false, input: false }, language: { type: 'string', required: false, input: false }, country: { type: 'string', required: false, input: false }, timezone: { type: 'string', required: false, input: false }, initialized: { type: 'boolean', required: false, input: false, defaultValue: false }, lastUsedOrganizationId: { type: 'string', required: false, input: false } }, fields: {} } } satisfies BetterAuthOptions const auth = betterAuth(authConfig) export type UserSession = typeof auth.$Infer.Session ``` ### Additional context _No response_
GiteaMirror added the locked label 2026-04-15 17:52:40 -05:00
Author
Owner

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

This is a known limitation in Better Auth v1.4.1: typeof auth.$Infer.Session does not include additionalFields from your user config because $Infer is a runtime helper and TypeScript can't link it to your config statically. This isn't a bug, but a side effect of how type inference works in the current version (details).

Workarounds:

  • Use ReturnType<typeof betterAuth<typeof config>> to define your Auth type, then reference types from that. For example:
    type Auth = ReturnType<typeof betterAuth<typeof authConfig>>;
    export const auth: Auth = betterAuth(authConfig);
    export type UserSession = Auth["$Infer"]["Session"];
    
  • Or, use Awaited<ReturnType<typeof auth.api.getSession>> to infer the session type, but this can break with complex plugin setups (source).
  • For strict type safety, some users use schema tools like drizzle-zod to generate types from their DB schema (example).

If you want the additional fields to appear at runtime in the session/user object, make sure those fields are present in your database and returned by your adapter (explanation).

If you want a permanent fix, a recent PR #5735 (merged after v1.4.1) ensures additionalFields are included in the session and user objects. Upgrading to a version that includes this PR will resolve the issue.

Also, check your tsconfig.json—the exactOptionalPropertyTypes flag can break type inference for additional fields. Setting it to false may help (reference).

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:3568210310 --> @dosubot[bot] commented on GitHub (Nov 23, 2025): <!-- Answer --> This is a known limitation in Better Auth v1.4.1: `typeof auth.$Infer.Session` does not include `additionalFields` from your user config because `$Infer` is a runtime helper and TypeScript can't link it to your config statically. This isn't a bug, but a side effect of how type inference works in the current version ([details](https://github.com/better-auth/better-auth/issues/5462#issuecomment-3427220948)). Workarounds: - Use `ReturnType<typeof betterAuth<typeof config>>` to define your `Auth` type, then reference types from that. For example: ```ts type Auth = ReturnType<typeof betterAuth<typeof authConfig>>; export const auth: Auth = betterAuth(authConfig); export type UserSession = Auth["$Infer"]["Session"]; ``` - Or, use `Awaited<ReturnType<typeof auth.api.getSession>>` to infer the session type, but this can break with complex plugin setups ([source](https://github.com/better-auth/better-auth/issues/5462#issuecomment-3427220948)). - For strict type safety, some users use schema tools like drizzle-zod to generate types from their DB schema ([example](https://github.com/better-auth/better-auth/issues/5218)). If you want the additional fields to appear at runtime in the session/user object, make sure those fields are present in your database and returned by your adapter ([explanation](https://github.com/better-auth/better-auth/issues/3888)). If you want a permanent fix, a recent PR [#5735](https://github.com/better-auth/better-auth/pull/5735) (merged after v1.4.1) ensures `additionalFields` are included in the session and user objects. Upgrading to a version that includes this PR will resolve the issue. Also, check your `tsconfig.json`—the `exactOptionalPropertyTypes` flag can break type inference for additional fields. Setting it to `false` may help ([reference](https://github.com/better-auth/better-auth/issues/5159#issuecomment-3381729607)). <!-- 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/a74a8b38-9c92-42f5-9ffb-eec9232fc0aa?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/a74a8b38-9c92-42f5-9ffb-eec9232fc0aa?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/a74a8b38-9c92-42f5-9ffb-eec9232fc0aa?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/a74a8b38-9c92-42f5-9ffb-eec9232fc0aa?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/a74a8b38-9c92-42f5-9ffb-eec9232fc0aa?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/a74a8b38-9c92-42f5-9ffb-eec9232fc0aa?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/a74a8b38-9c92-42f5-9ffb-eec9232fc0aa?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20known%20limitation%20in%20Better%20Auth%20v1.4.1%3A%20%60typeof%20auth.%24Infer.Session%60%20does%20not%20include%20%60additionalFields%60%20from%20your%20user%20config%20because%20%60%24Infer%60%20is%20a%20runtime%20helper%20and%20TypeScript%20can%27t%20link%20it%20to%20your%20config%20statically.%20This%20isn%27t%20a%20bug%2C%20but%20a%20side%20effect%20of%20how%20type%20inference%20works%20in%20the%20current%20version%C2%A0%28%5Bdetails%5D%28https%3A//github.com/better-auth/better-auth/issues/5462%23issuecomment-3427220948%29%29.%0A%0AWorkarounds%3A%0A-%20Use%20%60ReturnType%3Ctypeof%20betterAuth%3Ctypeof%20config%3E%3E%60%20to%20define%20your%20%60Auth%60%20type%2C%20then%20reference%20types%20from%20that.%20For%20example%3A%0A%20%20%60%60%60ts%0A%20%20type%20Auth%20%3D%20ReturnType%3Ctypeof%20betterAuth%3Ctypeof%20authConfig%3E%3E%3B%0A%20%20export%20const%20auth%3A%20Auth%20%3D%20betterAuth%28authConfig%29%3B%0A%20%20export%20type%20UserSession%20%3D%20Auth%5B%22%24Infer%22%5D%5B%22Session%22%5D%3B%0A%20%20%60%60%60%0A-%20Or%2C%20use%20%60Awaited%3CReturnType%3Ctypeof%20auth.api.getSession%3E%3E%60%20to%20infer%20the%20session%20type%2C%20but%20this%20can%20break%20with%20complex%20plugin%20setups%C2%A0%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/5462%23issuecomment-3427220948%29%29.%0A-%20For%20strict%20type%20safety%2C%20some%20users%20use%20schema%20tools%20like%20drizzle-zod%20to%20generate%20types%20from%20their%20DB%20schema%C2%A0%28%5Bexample%5D%28https%3A//github.com/better-auth/better-auth/issues/5218%29%29.%0A%0AIf%20you%20want%20the%20additional%20fields%20to%20appear%20at%20runtime%20in%20the%20session/user%20object%2C%20make%20sure%20those%20fields%20are%20present%20in%20your%20database%20and%20returned%20by%20your%20adapter%C2%A0%28%5Bexplanation%5D%28https%3A//github.com/better-auth/better-auth/issues/3888%29%29.%0A%0AIf%20you%20want%20a%20permanent%20fix%2C%20a%20recent%20PR%C2%A0%5B%235735%5D%28https%3A//github.com/better-auth/better-auth/pull/5735%29%20%28merged%20after%20v1.4.1%29%20ensures%20%60additionalFields%60%20are%20included%20in%20the%20session%20and%20user%20objects.%20Upgrading%20to%20a%20version%20that%20includes%20this%20PR%20will%20resolve%20the%20issue.%0A%0AAlso%2C%20check%20your%20%60tsconfig.json%60%E2%80%94the%20%60exactOptionalPropertyTypes%60%20flag%20can%20break%20type%20inference%20for%20additional%20fields.%20Setting%20it%20to%20%60false%60%20may%20help%C2%A0%28%5Breference%5D%28https%3A//github.com/better-auth/better-auth/issues/5159%23issuecomment-3381729607%29%29.)&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/6239)
Author
Owner

@Bekacru commented on GitHub (Nov 24, 2025):

It’s happening because you’re using a custom session plugin. inferSession will only infer whatever the custom session function returns. In your case, the custom session isn’t exposing the additional fields, so the inference falls back to the base shape

<!-- gh-comment-id:3568801492 --> @Bekacru commented on GitHub (Nov 24, 2025): It’s happening because you’re using a custom session plugin. inferSession will only infer whatever the custom session function returns. In your case, the custom session isn’t exposing the additional fields, so the inference falls back to the base shape
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#19087