[GH-ISSUE #6332] TypeScript types for server-side auth.api.* methods incorrectly typed as Response instead of parsed objects #10486

Closed
opened 2026-04-13 06:40:04 -05:00 by GiteaMirror · 7 comments
Owner

Originally created by @phillipplum on GitHub (Nov 26, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/6332

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  import { betterAuth } from 'better-auth';
  import { admin } from 'better-auth/plugins';

  const auth = betterAuth({
    // ... config
    plugins: [admin()],
  });

  // Server-side API call
  const response = await auth.api.listUsers({
    headers: myHeaders,
    query: { limit: 10 },
  });

  // TypeScript shows `response` as type `Response`
  // But at runtime, it's actually: { users: User[], total: number, ... }

  console.log(response.total); // TS Error: Property 'total' does not exist on type 'Response'

Current vs. Expected behavior

Expected Behavior

TypeScript types should reflect the actual return types:

  // listUsers should return:
  type ListUsersResponse = {
    users: User[];
    total: number;
    limit?: number;
    offset?: number;
  };

  // createUser should return:
  type CreateUserResponse = {
    user: User;
  };

Actual Behavior

  • TypeScript types show Response as return type
  • The actual runtime return is the parsed object directly

What version of Better Auth are you using?

1.4.2

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.0.0: Wed Sep 17 21:35:32 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6020",
    "release": "25.0.0",
    "cpuCount": 12,
    "cpuModel": "Apple M2 Max",
    "totalMemory": "32.00 GB",
    "freeMemory": "0.16 GB"
  },
  "node": {
    "version": "v24.11.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.6.1"
  },
  "frameworks": null,
  "databases": null,
  "betterAuth": {
    "version": "Unknown",
    "config": null
  }
}

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  plugins: [admin()],
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

When using auth.api.listUsers() or auth.api.createUser() server-side, TypeScript types indicate the return type is Response, but at runtime the methods return parsed objects directly (not fetch-like Response objects).

This causes:

  1. TypeScript errors when trying to access properties like .total or .user
  2. Runtime errors when calling .json() on the response (which doesn't exist)

Workaround

Currently using type assertions:

const listUsersResponse = (await auth.api.listUsers({
  ...headers,
  query: { searchField: 'email', searchValue: email, limit: 1 },
})) as unknown as { users: unknown[]; total: number };
Originally created by @phillipplum on GitHub (Nov 26, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/6332 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce ``` import { betterAuth } from 'better-auth'; import { admin } from 'better-auth/plugins'; const auth = betterAuth({ // ... config plugins: [admin()], }); // Server-side API call const response = await auth.api.listUsers({ headers: myHeaders, query: { limit: 10 }, }); // TypeScript shows `response` as type `Response` // But at runtime, it's actually: { users: User[], total: number, ... } console.log(response.total); // TS Error: Property 'total' does not exist on type 'Response' ``` ### Current vs. Expected behavior **Expected Behavior** TypeScript types should reflect the actual return types: ``` // listUsers should return: type ListUsersResponse = { users: User[]; total: number; limit?: number; offset?: number; }; // createUser should return: type CreateUserResponse = { user: User; }; ``` **Actual Behavior** - TypeScript types show Response as return type - The actual runtime return is the parsed object directly ### What version of Better Auth are you using? 1.4.2 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.0.0: Wed Sep 17 21:35:32 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6020", "release": "25.0.0", "cpuCount": 12, "cpuModel": "Apple M2 Max", "totalMemory": "32.00 GB", "freeMemory": "0.16 GB" }, "node": { "version": "v24.11.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.6.1" }, "frameworks": null, "databases": null, "betterAuth": { "version": "Unknown", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ plugins: [admin()], emailAndPassword: { enabled: true }, }); ``` ### Additional context When using auth.api.listUsers() or auth.api.createUser() server-side, TypeScript types indicate the return type is Response, but at runtime the methods return parsed objects directly (not fetch-like Response objects). This causes: 1. TypeScript errors when trying to access properties like .total or .user 2. Runtime errors when calling .json() on the response (which doesn't exist) **Workaround** Currently using type assertions: ``` const listUsersResponse = (await auth.api.listUsers({ ...headers, query: { searchField: 'email', searchValue: email, limit: 1 }, })) as unknown as { users: unknown[]; total: number }; ```
GiteaMirror added the enhancementlocked labels 2026-04-13 06:40:04 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Nov 26, 2025):

tag @better-auth-agent if you would like an answer from the Agent

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3581089199 --> @better-auth-agent[bot] commented on GitHub (Nov 26, 2025): tag @better-auth-agent if you would like an answer from the Agent <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

@phillipplum commented on GitHub (Nov 26, 2025):

@better-auth-agent

<!-- gh-comment-id:3581104193 --> @phillipplum commented on GitHub (Nov 26, 2025): @better-auth-agent
Author
Owner

@better-auth-agent[bot] commented on GitHub (Nov 26, 2025):

Hi there! Thanks for reporting this issue. We’ve seen similar reports where server-side API methods return parsed objects rather than standard Response objects, which causes the TypeScript definitions to be off. In our latest updates, we’ve been working on improving the type annotations so that methods like listUsers and createUser correctly reflect the returned object types (e.g., ListUsersResponse and CreateUserResponse) rather than a generic Response. As a workaround, you can use type assertions until we release an update that aligns the TS types with runtime behavior.

I suggest verifying you’re using the latest version and checking our changelog for any upcoming fixes. If the issue still persists, please tag @bekacru and @ping__ so they can take a closer look.

Tag @better-auth-agent if you would like an answer from the Agent. How else can we help you with your Better Auth implementation?

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3581105645 --> @better-auth-agent[bot] commented on GitHub (Nov 26, 2025): Hi there! Thanks for reporting this issue. We’ve seen similar reports where server-side API methods return parsed objects rather than standard Response objects, which causes the TypeScript definitions to be off. In our latest updates, we’ve been working on improving the type annotations so that methods like listUsers and createUser correctly reflect the returned object types (e.g., ListUsersResponse and CreateUserResponse) rather than a generic Response. As a workaround, you can use type assertions until we release an update that aligns the TS types with runtime behavior. I suggest verifying you’re using the latest version and checking our changelog for any upcoming fixes. If the issue still persists, please tag @bekacru and @ping__ so they can take a closer look. Tag @better-auth-agent if you would like an answer from the Agent. How else can we help you with your Better Auth implementation? <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

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

You're right—server-side auth.api.* methods in Better Auth v1.4.2 are incorrectly typed as returning Response, but at runtime they return parsed objects like { users: User[], total: number } or { user: User }. This mismatch causes TypeScript errors when you try to access properties like .total or .user, and runtime errors if you call .json() on the result. The root cause is incomplete type propagation and conflicting type definitions in the codebase, especially when plugins or custom fields are involved. The API surface is built using type inference from endpoint definitions, but the actual return types aren't explicitly propagated, so TypeScript falls back to Response or unknown types [details].

This is a known issue, confirmed by maintainers and other users [details]. The recommended workaround is to manually cast the return value to the expected type using type assertions, like:

const response = await auth.api.listUsers({ headers, query: { limit: 10 } }) as { users: User[]; total: number };

Until a fix is released, continue using type assertions or manually extend the types locally. If you use custom user fields, you may need to extend the type further to match your schema. There are no recent pull requests addressing this for the main API surface, so keep an eye on updates and changelogs for future improvements.

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:3581105927 --> @dosubot[bot] commented on GitHub (Nov 26, 2025): <!-- Answer --> You're right—server-side `auth.api.*` methods in Better Auth v1.4.2 are incorrectly typed as returning `Response`, but at runtime they return parsed objects like `{ users: User[], total: number }` or `{ user: User }`. This mismatch causes TypeScript errors when you try to access properties like `.total` or `.user`, and runtime errors if you call `.json()` on the result. The root cause is incomplete type propagation and conflicting type definitions in the codebase, especially when plugins or custom fields are involved. The API surface is built using type inference from endpoint definitions, but the actual return types aren't explicitly propagated, so TypeScript falls back to `Response` or `unknown` types [[details](https://github.com/better-auth/better-auth/issues/4584)]. This is a known issue, confirmed by maintainers and other users [[details](https://github.com/better-auth/better-auth/issues/6318)]. The recommended workaround is to manually cast the return value to the expected type using type assertions, like: ```ts const response = await auth.api.listUsers({ headers, query: { limit: 10 } }) as { users: User[]; total: number }; ``` Until a fix is released, continue using type assertions or manually extend the types locally. If you use custom user fields, you may need to extend the type further to match your schema. There are no recent pull requests addressing this for the main API surface, so keep an eye on updates and changelogs for future improvements. <!-- 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/c090d73b-e960-4db7-988b-39d9db3a0ebd?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/c090d73b-e960-4db7-988b-39d9db3a0ebd?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/c090d73b-e960-4db7-988b-39d9db3a0ebd?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/c090d73b-e960-4db7-988b-39d9db3a0ebd?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/c090d73b-e960-4db7-988b-39d9db3a0ebd?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/c090d73b-e960-4db7-988b-39d9db3a0ebd?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/c090d73b-e960-4db7-988b-39d9db3a0ebd?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=You%27re%20right%E2%80%94server-side%20%60auth.api.%2A%60%20methods%20in%20Better%20Auth%20v1.4.2%20are%20incorrectly%20typed%20as%20returning%20%60Response%60%2C%20but%20at%20runtime%20they%20return%20parsed%20objects%20like%20%60%7B%20users%3A%20User%5B%5D%2C%20total%3A%20number%20%7D%60%20or%20%60%7B%20user%3A%20User%20%7D%60.%20This%20mismatch%20causes%20TypeScript%20errors%20when%20you%20try%20to%20access%20properties%20like%20%60.total%60%20or%20%60.user%60%2C%20and%20runtime%20errors%20if%20you%20call%20%60.json%28%29%60%20on%20the%20result.%20The%20root%20cause%20is%20incomplete%20type%20propagation%20and%20conflicting%20type%20definitions%20in%20the%20codebase%2C%20especially%20when%20plugins%20or%20custom%20fields%20are%20involved.%20The%20API%20surface%20is%20built%20using%20type%20inference%20from%20endpoint%20definitions%2C%20but%20the%20actual%20return%20types%20aren%27t%20explicitly%20propagated%2C%20so%20TypeScript%20falls%20back%20to%20%60Response%60%20or%20%60unknown%60%20types%20%5B%5Bdetails%5D%28https%3A//github.com/better-auth/better-auth/issues/4584%29%5D.%0A%0AThis%20is%20a%20known%20issue%2C%20confirmed%20by%20maintainers%20and%20other%20users%20%5B%5Bdetails%5D%28https%3A//github.com/better-auth/better-auth/issues/6318%29%5D.%20The%20recommended%20workaround%20is%20to%20manually%20cast%20the%20return%20value%20to%20the%20expected%20type%20using%20type%20assertions%2C%20like%3A%0A%0A%60%60%60ts%0Aconst%20response%20%3D%20await%20auth.api.listUsers%28%7B%20headers%2C%20query%3A%20%7B%20limit%3A%2010%20%7D%20%7D%29%20as%20%7B%20users%3A%20User%5B%5D%3B%20total%3A%20number%20%7D%3B%0A%60%60%60%0A%0AUntil%20a%20fix%20is%20released%2C%20continue%20using%20type%20assertions%20or%20manually%20extend%20the%20types%20locally.%20If%20you%20use%20custom%20user%20fields%2C%20you%20may%20need%20to%20extend%20the%20type%20further%20to%20match%20your%20schema.%20There%20are%20no%20recent%20pull%20requests%20addressing%20this%20for%20the%20main%20API%20surface%2C%20so%20keep%20an%20eye%20on%20updates%20and%20changelogs%20for%20future%20improvements.)&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/6332)
Author
Owner

@better-auth-agent[bot] commented on GitHub (Nov 26, 2025):

It sounds like you're encountering the same issue where your extended user fields, although present in your database, aren’t being mapped and returned in the API response. This is a known challenge—when you extend the core user schema via the auth configuration, the extended fields might not be automatically included in the response, which has been observed in previous reports [1].

A few steps you might consider:
• Verify your auth configuration to ensure that your extended user fields are correctly defined as part of the schema.
• Check if a migration is needed so that the new schema, including the extended fields, is correctly applied.
• Look into any recent release notes or updated documentation regarding custom/extended user fields; there may be additional configuration or a workaround required to have them returned in the response.

Could you confirm that you’ve applied the latest migration and that your extended fields are correctly configured in your auth setup? Tag @better-auth-agent if you would like an answer from the Agent.

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3582031924 --> @better-auth-agent[bot] commented on GitHub (Nov 26, 2025): It sounds like you're encountering the same issue where your extended user fields, although present in your database, aren’t being mapped and returned in the API response. This is a known challenge—when you extend the core user schema via the auth configuration, the extended fields might not be automatically included in the response, which has been observed in previous reports [[1]](https://github.com/better-auth/better-auth/issues/6332). A few steps you might consider: • Verify your auth configuration to ensure that your extended user fields are correctly defined as part of the schema. • Check if a migration is needed so that the new schema, including the extended fields, is correctly applied. • Look into any recent release notes or updated documentation regarding custom/extended user fields; there may be additional configuration or a workaround required to have them returned in the response. Could you confirm that you’ve applied the latest migration and that your extended fields are correctly configured in your auth setup? Tag @better-auth-agent if you would like an answer from the Agent. <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

@ping-maxwell commented on GitHub (Jan 8, 2026):

Hello testing your setup works fine on my end, I don't see a Response type 🤔
Could you try on the latest version of Better Auth and report back? Thanks.

<!-- gh-comment-id:3723984521 --> @ping-maxwell commented on GitHub (Jan 8, 2026): Hello testing your setup works fine on my end, I don't see a `Response` type 🤔 Could you try on the latest version of Better Auth and report back? Thanks.
Author
Owner

@phillipplum commented on GitHub (Jan 10, 2026):

Hello testing your setup works fine on my end, I don't see a Response type 🤔 Could you try on the latest version of Better Auth and report back? Thanks.

Yes, now it works fine!

<!-- gh-comment-id:3731154433 --> @phillipplum commented on GitHub (Jan 10, 2026): > Hello testing your setup works fine on my end, I don't see a `Response` type 🤔 Could you try on the latest version of Better Auth and report back? Thanks. Yes, now it works fine!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10486