[GH-ISSUE #3780] Type issue when using "auth.api.getSession" #9723

Closed
opened 2026-04-13 05:23:52 -05:00 by GiteaMirror · 9 comments
Owner

Originally created by @kevinmarrec on GitHub (Aug 4, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3780

To Reproduce

  1. Create a backend
  2. Use auth.api.getSession
  3. The endpoint signature does not allow to use returnHeaders option

Current vs. Expected behavior

Current :

  • No returnHeaders option for getSession endpoint
Image

Note: Still, we can force the returnHeaders option (even if not typed) and it will work as expected but with many typscript errors ! 👇

Image

Expected :

  • Having returnHeaders option + correct typings when using the option, like other endpoints, here is an example with signUpEmail endpoint :
Image

We should have no problem using the following code :

const { headers, response } = await auth.api.getSession({
  headers,
  returnHeaders: true
}

console.log(headers) // Should be of type Headers
console.log(response) // Should be of type { session: ..., user: ... }

What version of Better Auth are you using?

1.3.4

Provide environment information

OS: Ubuntu

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

Backend

Auth config (if applicable)

import { betterAuth } from 'better-auth'

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
  },
})

Additional context

https://github.com/better-auth/better-auth/issues/2115
https://github.com/better-auth/better-auth/issues/2115#issuecomment-3069526380

It looks like there a big type issue, as using "Go to Type Definition" on getSession leads to this :

Image

Meanwhile other endpoints lead to a definition where there is all other endpoints :

Image

And the big surprise, there is another getSession definition there that looks correctly typed :

Image

So overall I think there's something in the types that override this correctly typed getSession endpoint by a wrong typed getSession endpoint (the one with InferAPI thing)

Originally created by @kevinmarrec on GitHub (Aug 4, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3780 ### To Reproduce 1. Create a backend 2. Use `auth.api.getSession` 3. The endpoint signature does not allow to use `returnHeaders` option ### Current vs. Expected behavior **Current** : - No `returnHeaders` option for `getSession` endpoint <img width="799" height="120" alt="Image" src="https://github.com/user-attachments/assets/d922d6be-feca-4dec-b385-92357b0a2a62" /> *__Note__: Still, we can force the `returnHeaders` option (even if not typed) and it will work as expected but with many typscript errors !* 👇 <img width="685" height="79" alt="Image" src="https://github.com/user-attachments/assets/3d642473-5e5d-48a2-9086-72b6903b8c81" /> **Expected** : - Having `returnHeaders` option + correct typings when using the option, like other endpoints, here is an example with `signUpEmail` endpoint : <img width="1121" height="336" alt="Image" src="https://github.com/user-attachments/assets/236156e6-6286-49fe-8cea-e18cfe9faa91" /> We should have no problem using the following code : ```ts const { headers, response } = await auth.api.getSession({ headers, returnHeaders: true } console.log(headers) // Should be of type Headers console.log(response) // Should be of type { session: ..., user: ... } ``` ### What version of Better Auth are you using? 1.3.4 ### Provide environment information ```bash OS: Ubuntu ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from 'better-auth' export const auth = betterAuth({ emailAndPassword: { enabled: true, }, }) ``` ### Additional context https://github.com/better-auth/better-auth/issues/2115 https://github.com/better-auth/better-auth/issues/2115#issuecomment-3069526380 It looks like there a big type issue, as using "Go to Type Definition" on `getSession` leads to this : <img width="732" height="330" alt="Image" src="https://github.com/user-attachments/assets/a504db9c-557f-4113-baf8-788047018b58" /> Meanwhile other endpoints lead to a definition where there is all other endpoints : <img width="908" height="353" alt="Image" src="https://github.com/user-attachments/assets/b572e49d-834d-4023-b683-badb13ff5424" /> And the big surprise, there is another `getSession` definition there that looks correctly typed : <img width="828" height="425" alt="Image" src="https://github.com/user-attachments/assets/dbce0937-b8f6-4525-88d1-e1a2ee2c3b72" /> So overall I think there's something in the types that override this correctly typed `getSession` endpoint by a wrong typed `getSession` endpoint (the one with `InferAPI` thing)
GiteaMirror added the locked label 2026-04-13 05:23:53 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 4, 2025):

Hi @kevinmarrec! I'm Dosu and I’m helping the better-auth team.

You're right—there's a type issue with auth.api.getSession in Better Auth v1.3.4: the returnHeaders option isn't properly typed, even though it works at runtime if you force it. This happens because the type for getSession is inferred through a generic system (InferAPI), which doesn't handle special-case options like returnHeaders as precisely as endpoints like signUpEmail do. As a result, TypeScript errors appear, and intellisense is incomplete, even though the endpoint itself works as expected.

There are actually two definitions for getSession in the codebase: one is correctly typed (with proper returnHeaders support), but it's overridden by the more generic, less precise type generated by the API inference system. This is a common pitfall in frameworks that generate endpoint types dynamically—special-case parameters can get dropped or overgeneralized in the process, leading to the exact issue you're seeing. Other endpoints like signUpEmail have more explicit typings, so they don't have this problem citation.

Workarounds:

  • You can use a type assertion or manually cast the return type when calling getSession to suppress TypeScript errors.
  • If you're using custom fields or plugins, consider using the inferAdditionalFields plugin on the client side to improve type inference for session-related endpoints citation.
  • As a last resort, manually cast the session type in your code where needed.

This type inference issue is known and discussed in several related issues (#2115, #1194, #2818, #3328). Runtime/session context bugs in getSession have been fixed in recent PRs, but the typing problem for returnHeaders remains citation.

Keep an eye on future releases for a proper fix. For now, type assertions or the inferAdditionalFields plugin are your best options.

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:3150825007 --> @dosubot[bot] commented on GitHub (Aug 4, 2025): <!-- Greeting --> Hi @kevinmarrec! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> You're right—there's a type issue with `auth.api.getSession` in Better Auth v1.3.4: the `returnHeaders` option isn't properly typed, even though it works at runtime if you force it. This happens because the type for `getSession` is inferred through a generic system (`InferAPI`), which doesn't handle special-case options like `returnHeaders` as precisely as endpoints like `signUpEmail` do. As a result, TypeScript errors appear, and intellisense is incomplete, even though the endpoint itself works as expected. There are actually two definitions for `getSession` in the codebase: one is correctly typed (with proper `returnHeaders` support), but it's overridden by the more generic, less precise type generated by the API inference system. This is a common pitfall in frameworks that generate endpoint types dynamically—special-case parameters can get dropped or overgeneralized in the process, leading to the exact issue you're seeing. Other endpoints like `signUpEmail` have more explicit typings, so they don't have this problem [citation](https://github.com/better-auth/better-auth/blob/987be984b4d840a409ca1e0d6098ee0f3303bcb6/packages/better-auth/src/api/index.ts). Workarounds: - You can use a type assertion or manually cast the return type when calling `getSession` to suppress TypeScript errors. - If you're using custom fields or plugins, consider using the `inferAdditionalFields` plugin on the client side to improve type inference for session-related endpoints [citation](https://github.com/better-auth/better-auth/issues/3328). - As a last resort, manually cast the session type in your code where needed. This type inference issue is known and discussed in several related issues ([#2115](https://github.com/better-auth/better-auth/issues/2115), [#1194](https://github.com/better-auth/better-auth/issues/1194), [#2818](https://github.com/better-auth/better-auth/issues/2818), [#3328](https://github.com/better-auth/better-auth/issues/3328)). Runtime/session context bugs in `getSession` have been fixed in recent PRs, but the typing problem for `returnHeaders` remains [citation](https://github.com/better-auth/better-auth/pull/3578). Keep an eye on future releases for a proper fix. For now, type assertions or the `inferAdditionalFields` plugin are your best options. <!-- 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/03fa09b3-6f0c-4c64-99c5-ad4301d902b5?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/03fa09b3-6f0c-4c64-99c5-ad4301d902b5?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/03fa09b3-6f0c-4c64-99c5-ad4301d902b5?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/03fa09b3-6f0c-4c64-99c5-ad4301d902b5?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/03fa09b3-6f0c-4c64-99c5-ad4301d902b5?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/03fa09b3-6f0c-4c64-99c5-ad4301d902b5?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/03fa09b3-6f0c-4c64-99c5-ad4301d902b5?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/3780)
Author
Owner

@kevinmarrec commented on GitHub (Aug 4, 2025):

As for now the more suitable workaround is one of the bot (@Dosubot) suggestion, which would look like something like this :

const response = await context.auth.api.getSession({
      headers: context.request.headers,
      asResponse: true,
    })

const session = await response.json() as typeof context.auth.$Infer.Session | null

I think that using context.auth.$Infer.Session make it correctly typed with custom session plugin as well.

That said, hopefully we'll have a better solution by making getSession types better and smarter, which would mean handling returnsHeader option, while using InferAPI generic system which seems to be the problem today.

<!-- gh-comment-id:3150860092 --> @kevinmarrec commented on GitHub (Aug 4, 2025): As for now the more suitable workaround is one of the bot (**@Dosubot**) suggestion, which would look like something like this : ```ts const response = await context.auth.api.getSession({ headers: context.request.headers, asResponse: true, }) const session = await response.json() as typeof context.auth.$Infer.Session | null ``` I think that using `context.auth.$Infer.Session` make it correctly typed with custom session plugin as well. That said, hopefully we'll have a better solution by making `getSession` types better and smarter, which would mean handling `returnsHeader` option, while using `InferAPI` generic system which seems to be the problem today.
Author
Owner

@frectonz commented on GitHub (Aug 13, 2025):

asResponse is a good way to handle this. I just created a PR to add returnHeaders to getSession.

@kevinmarrec I was wondering why do you want to get the headers returned by getSession.

<!-- gh-comment-id:3185755274 --> @frectonz commented on GitHub (Aug 13, 2025): `asResponse` is a good way to handle this. I just created a PR to add `returnHeaders` to `getSession`. @kevinmarrec I was wondering why do you want to get the headers returned by `getSession`.
Author
Owner

@kevinmarrec commented on GitHub (Aug 13, 2025):

@frectonz I want to get access to cookie headers generated by getSession when updateAge occurs (session refresh), so I can return it to my client (I'm not using better-auth client for client bundle optimization)

<!-- gh-comment-id:3185844171 --> @kevinmarrec commented on GitHub (Aug 13, 2025): @frectonz I want to get access to cookie headers generated by `getSession` when updateAge occurs (session refresh), so I can return it to my client (I'm not using better-auth client for client bundle optimization)
Author
Owner

@frectonz commented on GitHub (Aug 14, 2025):

@kevinmarrec I understand what you want to do, seems like #3983 correctly address the problem you are facing.

<!-- gh-comment-id:3188254273 --> @frectonz commented on GitHub (Aug 14, 2025): @kevinmarrec I understand what you want to do, seems like #3983 correctly address the problem you are facing.
Author
Owner

@kevinmarrec commented on GitHub (Aug 14, 2025):

@frectonz Indeed the solution seems to perfectly fit the need, thanks !

<!-- gh-comment-id:3189412729 --> @kevinmarrec commented on GitHub (Aug 14, 2025): @frectonz Indeed the solution seems to perfectly fit the need, thanks !
Author
Owner

@mhornbacher commented on GitHub (Aug 18, 2025):

Hi everyone,

I’m not sure if this is directly related to the current discussion, but I noticed that if zod is not listed as a dependency of the project, this change in version 1.3.7 seems to break the types, causing most types to resolve as any. I had to add zod as a devDependency and reset my lock file in order to resolve it.

Just wanted to flag it in case it’s helpful for debugging or planning a fix.

<!-- gh-comment-id:3195228875 --> @mhornbacher commented on GitHub (Aug 18, 2025): Hi everyone, I’m not sure if this is directly related to the current discussion, but I noticed that if zod is not listed as a dependency of the project, [this change](https://github.com/better-auth/better-auth/compare/v1.3.6...v1.3.7#diff-5fa366118e2fc5e98f8dbce4eb9fffc7f5a57c2bed3815cd9aebdb374c717fc8R53) in version 1.3.7 seems to break the types, causing most types to resolve as any. I had to add `zod` as a `devDependency` and reset my lock file in order to resolve it. Just wanted to flag it in case it’s helpful for debugging or planning a fix.
Author
Owner

@widavies commented on GitHub (Mar 26, 2026):

Are returnHeaders or asResponse available for the client variants as well (authClient.getSession and authClient.useSession)?

It would be nice to have access to the headers & other response metadata returned by the server. In particular, I set the JWT in a header using an after hook in /get-session. It would be nice to have it immediately ready for use rather than also having to wait until authClient.token() completes.

I patched better-auth to achieve this for my use case - I added headers to the useAuthQuery atoms, is this something you'd be interested in for a PR?

Looks like this might also be possible with better fetch plugins as an alternative?

@Bekacru @frectonz

<!-- gh-comment-id:4131402761 --> @widavies commented on GitHub (Mar 26, 2026): Are `returnHeaders` or `asResponse` available for the client variants as well (`authClient.getSession` and `authClient.useSession`)? It would be nice to have access to the headers & other response metadata returned by the server. In particular, I set the JWT in a header using an after hook in `/get-session`. It would be nice to have it immediately ready for use rather than also having to wait until `authClient.token()` completes. I patched better-auth to achieve this for my use case - I added `headers` to the `useAuthQuery` atoms, is this something you'd be interested in for a PR? Looks like this might also be possible with better fetch plugins as an alternative? @Bekacru @frectonz
Author
Owner

@github-actions[bot] commented on GitHub (Apr 3, 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:4181127439 --> @github-actions[bot] commented on GitHub (Apr 3, 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#9723