[GH-ISSUE #4875] auth.$Infer.Session does not respect customSession plugin #18729

Closed
opened 2026-04-15 17:21:22 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @timheerwagen on GitHub (Sep 24, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/4875

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Minimal reproduction: https://github.com/timheerwagen/better-auth-infer-session-bug

  1. Install TypeScript.
  2. Check the types in src/auth/index.ts.
  3. Optionally, check the types in src/auth/client.ts.

Current vs. Expected behavior

authClient.$Infer.Session outputs the correct custom session from the plugin, but auth.$Infer.Session always returns the default session type.

A workaround that worked in Version 1.3.5 does not work anymore in 1.3.16.

export type WorkaroundServerSession = Awaited<
  ReturnType<typeof auth.api.getSession>
>;

I expect the returned session type to be the same as the one in customSession.

What version of Better Auth are you using?

1.3.5 - 1.3.16

System info

{
  "system": {
    "platform": "win32",
    "arch": "x64",
    "version": "Windows 11 Pro",
    "release": "10.0.26100",
    "cpuCount": 12,
    "cpuModel": "Intel(R) Core(TM) i5-10600K CPU @ 4.10GHz",
    "totalMemory": "15.91 GB",
    "freeMemory": "3.49 GB"
  },
  "node": {
    "version": "v22.13.1",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.4.2"
  },
  "frameworks": null,
  "databases": null,
  "betterAuth": {
    "version": "1.3.5",
    "config": null
  }
}

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

Types

Auth config (if applicable)

export const auth = betterAuth({
  basePath: "/api/internal/auth",
  plugins: [
    customSession(async ({ session }) => {
      const ownUser = { some: "thing" } as const;

      return {
        user: ownUser,
        session,
      };
    }),
  ],
});

Additional context

No response

Originally created by @timheerwagen on GitHub (Sep 24, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/4875 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Minimal reproduction: https://github.com/timheerwagen/better-auth-infer-session-bug 1. Install TypeScript. 2. Check the types in src/auth/index.ts. 3. Optionally, check the types in src/auth/client.ts. ### Current vs. Expected behavior `authClient.$Infer.Session` outputs the correct custom session from the plugin, but `auth.$Infer.Session` always returns the default session type. A workaround that worked in Version 1.3.5 does not work anymore in 1.3.16. ```ts export type WorkaroundServerSession = Awaited< ReturnType<typeof auth.api.getSession> >; ``` I expect the returned session type to be the same as the one in customSession. ### What version of Better Auth are you using? 1.3.5 - 1.3.16 ### System info ```bash { "system": { "platform": "win32", "arch": "x64", "version": "Windows 11 Pro", "release": "10.0.26100", "cpuCount": 12, "cpuModel": "Intel(R) Core(TM) i5-10600K CPU @ 4.10GHz", "totalMemory": "15.91 GB", "freeMemory": "3.49 GB" }, "node": { "version": "v22.13.1", "env": "development" }, "packageManager": { "name": "npm", "version": "11.4.2" }, "frameworks": null, "databases": null, "betterAuth": { "version": "1.3.5", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Types ### Auth config (if applicable) ```typescript export const auth = betterAuth({ basePath: "/api/internal/auth", plugins: [ customSession(async ({ session }) => { const ownUser = { some: "thing" } as const; return { user: ownUser, session, }; }), ], }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-15 17:21:22 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 24, 2025):

This is a known limitation in Better Auth's type inference system: server-side auth.$Infer.Session doesn't always pick up custom session types from the customSession plugin, even though the client-side inference works as expected. This happens because TypeScript can't always propagate plugin generics through the server API, especially when multiple plugins or custom fields are involved. The workaround using Awaited<ReturnType<typeof auth.api.getSession>> worked in earlier versions but can break with recent changes to type inference logic or when more plugins are added [source].

Recommended workarounds:

  • Define your Better Auth options separately (using satisfies BetterAuthOptions), then pass those options to customSession so TypeScript can infer all plugin-added fields [source].
  • Ensure customSession is placed after other plugins in your plugins array to avoid losing properties added by other plugins [source].
  • If inference still fails, use a type assertion when parsing the session response, e.g.:
    const response = await auth.api.getSession({ asResponse: true });
    const session = await response.json() as typeof auth.$Infer.Session | null;
    
    [source]

This isn't considered a runtime bug but a limitation of the current plugin/type system and TypeScript's inference model in Better Auth [source]. If you need to guarantee type safety, manual type assertions are the safest fallback for now.

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:3328487387 --> @dosubot[bot] commented on GitHub (Sep 24, 2025): <!-- Answer --> This is a known limitation in Better Auth's type inference system: server-side `auth.$Infer.Session` doesn't always pick up custom session types from the `customSession` plugin, even though the client-side inference works as expected. This happens because TypeScript can't always propagate plugin generics through the server API, especially when multiple plugins or custom fields are involved. The workaround using `Awaited<ReturnType<typeof auth.api.getSession>>` worked in earlier versions but can break with recent changes to type inference logic or when more plugins are added [[source](https://github.com/better-auth/better-auth/issues/2818)]. Recommended workarounds: - Define your Better Auth options separately (using `satisfies BetterAuthOptions`), then pass those options to `customSession` so TypeScript can infer all plugin-added fields [[source](https://github.com/better-auth/better-auth/issues/3233#issuecomment-3021659951)]. - Ensure `customSession` is placed after other plugins in your plugins array to avoid losing properties added by other plugins [[source](https://github.com/better-auth/better-auth/issues/3233#issuecomment-3021659951)]. - If inference still fails, use a type assertion when parsing the session response, e.g.: ```ts const response = await auth.api.getSession({ asResponse: true }); const session = await response.json() as typeof auth.$Infer.Session | null; ``` [[source](https://github.com/better-auth/better-auth/issues/3780)] This isn't considered a runtime bug but a limitation of the current plugin/type system and TypeScript's inference model in Better Auth [[source](https://github.com/better-auth/better-auth/issues/3233#issuecomment-3021659951)]. If you need to guarantee type safety, manual type assertions are the safest fallback for now. <!-- 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/d744b9a9-e774-4df2-a058-50a6b5237f71?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d744b9a9-e774-4df2-a058-50a6b5237f71?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d744b9a9-e774-4df2-a058-50a6b5237f71?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d744b9a9-e774-4df2-a058-50a6b5237f71?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d744b9a9-e774-4df2-a058-50a6b5237f71?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d744b9a9-e774-4df2-a058-50a6b5237f71?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d744b9a9-e774-4df2-a058-50a6b5237f71?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/4875)
Author
Owner

@merthanmerter commented on GitHub (Oct 1, 2025):

This started failing after 1.3.19 again.

<!-- gh-comment-id:3356329463 --> @merthanmerter commented on GitHub (Oct 1, 2025): This started failing after 1.3.19 again.
Author
Owner

@j-fdion commented on GitHub (Oct 2, 2025):

This worked for me:

https://github.com/better-auth/better-auth/issues/3408#issuecomment-3362114564

<!-- gh-comment-id:3362445265 --> @j-fdion commented on GitHub (Oct 2, 2025): This worked for me: [https://github.com/better-auth/better-auth/issues/3408#issuecomment-3362114564](https://github.com/better-auth/better-auth/issues/3408#issuecomment-3362114564)
Author
Owner

@Pyakz commented on GitHub (Jan 19, 2026):

using "better-auth": "^1.4.6", this is still a thiing

<!-- gh-comment-id:3768210639 --> @Pyakz commented on GitHub (Jan 19, 2026): using "better-auth": "^1.4.6", this is still a thiing
Author
Owner

@github-actions[bot] commented on GitHub (Apr 1, 2026):

This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.

<!-- gh-comment-id:4166563985 --> @github-actions[bot] commented on GitHub (Apr 1, 2026): This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#18729