Unclear typing change for runWithEndpointContext in v1.5 #2958

Closed
opened 2026-03-13 10:30:32 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @MrLightful on GitHub (Mar 2, 2026).

Originally assigned to: @himself65 on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Write a server action:

const context = await auth.$context;
const user = await runWithEndpointContext({ context }, () => {});

Observe typing error.

Current vs. Expected behavior

After upgrading better-auth to v1.5, runWithEndpointContext started throwing type error.

Previously, I was using it as such:

const context = await auth.$context;
const user = await runWithEndpointContext({ context }, () => {});

However, now it produces a type error on context argument:

Error ``` Type 'PluginContext<{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }> & InfoContext & { ...; }' is not assignable to type 'Record & { [x: string]: any; } & PluginContext & InfoContext & { options: BetterAuthOptions; ... 26 more ...; runInBackgroundOrAwait: (promise: void | Promise<...>) => unknown; }'. Type 'PluginContext<{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }> & InfoContext & { ...; }' is not assignable to type '{ options: BetterAuthOptions; trustedOrigins: string[]; trustedProviders: string[]; isTrustedOrigin: (url: string, settings?: { allowRelativePaths: boolean; } | undefined) => boolean; ... 23 more ...; runInBackgroundOrAwait: (promise: void | Promise<...>) => unknown; }'. Types of property 'adapter' are incompatible. Type 'DBAdapter<{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }>' is not assignable to type 'DBAdapter'. Type 'BetterAuthOptions' is not assignable to type '{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }'. Types of property 'plugins' are incompatible. Type '[] | BetterAuthPlugin[] | undefined' is not assignable to type '[{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]'. Type 'undefined' is not assignable to type '[{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]'.ts(2322) context.d.mts(74, 3): The expected type comes from property 'context' which is declared here on type 'AuthEndpointContext' ```

There isn't much docs on runWithEndpointContext, so it's unclear what migration should look like.

What version of Better Auth are you using?

1.5.1

System info

{
  "system": {
    "platform": "win32",
    "arch": "x64",
    "version": "Windows 11 Enterprise",
    "release": "10.0.26200",
    "cpuCount": 14,
    "cpuModel": "Intel(R) Core(TM) Ultra 5 125U",
    "totalMemory": "15.47 GB",
    "freeMemory": "1.78 GB"
  },
  "node": {
    "version": "v25.7.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.10.1"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "^16.1.6"
    },
    {
      "name": "react",
      "version": "^19.2.4"
    }
  ],
  "databases": [
    {
      "name": "postgres",
      "version": "^3.4.8"
    },
    {
      "name": "drizzle",
      "version": "^0.45.1"
    }
  ],
  "betterAuth": {
    "version": "^1.5.1",
    "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({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

No response

Originally created by @MrLightful on GitHub (Mar 2, 2026). Originally assigned to: @himself65 on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Write a server action: ``` const context = await auth.$context; const user = await runWithEndpointContext({ context }, () => {}); ``` Observe typing error. ### Current vs. Expected behavior After upgrading better-auth to v1.5, `runWithEndpointContext` started throwing type error. Previously, I was using it as such: ``` const context = await auth.$context; const user = await runWithEndpointContext({ context }, () => {}); ``` However, now it produces a type error on context argument: <details><summary>Error</summary> ``` Type 'PluginContext<{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }> & InfoContext & { ...; }' is not assignable to type 'Record<string, any> & { [x: string]: any; } & PluginContext<BetterAuthOptions> & InfoContext & { options: BetterAuthOptions; ... 26 more ...; runInBackgroundOrAwait: (promise: void | Promise<...>) => unknown; }'. Type 'PluginContext<{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }> & InfoContext & { ...; }' is not assignable to type '{ options: BetterAuthOptions; trustedOrigins: string[]; trustedProviders: string[]; isTrustedOrigin: (url: string, settings?: { allowRelativePaths: boolean; } | undefined) => boolean; ... 23 more ...; runInBackgroundOrAwait: (promise: void | Promise<...>) => unknown; }'. Types of property 'adapter' are incompatible. Type 'DBAdapter<{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }>' is not assignable to type 'DBAdapter<BetterAuthOptions>'. Type 'BetterAuthOptions' is not assignable to type '{ plugins: [{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]; ... 8 more ...; onAPIError: { ...; }; }'. Types of property 'plugins' are incompatible. Type '[] | BetterAuthPlugin[] | undefined' is not assignable to type '[{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]'. Type 'undefined' is not assignable to type '[{ id: "next-cookies"; hooks: { before: { matcher(ctx: HookEndpointContext): boolean; handler: (inputContext: MiddlewareInputContext<MiddlewareOptions>) => Promise<...>; }[]; after: { ...; }[]; }; }, { ...; }]'.ts(2322) context.d.mts(74, 3): The expected type comes from property 'context' which is declared here on type 'AuthEndpointContext' ``` </details> There isn't much docs on `runWithEndpointContext`, so it's unclear what migration should look like. ### What version of Better Auth are you using? 1.5.1 ### System info ```bash { "system": { "platform": "win32", "arch": "x64", "version": "Windows 11 Enterprise", "release": "10.0.26200", "cpuCount": 14, "cpuModel": "Intel(R) Core(TM) Ultra 5 125U", "totalMemory": "15.47 GB", "freeMemory": "1.78 GB" }, "node": { "version": "v25.7.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.10.1" }, "frameworks": [ { "name": "next", "version": "^16.1.6" }, { "name": "react", "version": "^19.2.4" } ], "databases": [ { "name": "postgres", "version": "^3.4.8" }, { "name": "drizzle", "version": "^0.45.1" } ], "betterAuth": { "version": "^1.5.1", "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({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-03-13 10:30:32 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Mar 2, 2026):

This type error is caused by stricter type checking introduced in v1.5 via PR #5359. Your code pattern was structurally correct, but the types are now more restrictive.

Quick fix - Use a type assertion:

import { GenericEndpointContext } from "better-auth";

const context = await auth.$context;
const user = await runWithEndpointContext(
  { context } as GenericEndpointContext,
  () => context.internalAdapter.createUser({
    email,
    name,
    role,
    invitedBy: invitedBy.id,
  }),
);

Recommended approach - Use auth.api instead, which doesn't require runWithEndpointContext:

const user = await auth.api.signUpEmail({
  body: { email, name, password },
});

The maintainers discourage using auth.$context outside endpoint scope and recommend auth.api for server-side operations. If you need direct adapter access, the admin plugin provides server-side APIs for user management.

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

@dosubot[bot] commented on GitHub (Mar 2, 2026): <!-- Answer --> This type error is caused by stricter type checking introduced in v1.5 via [PR #5359](https://github.com/better-auth/better-auth/pull/5359). Your code pattern was structurally correct, but the types are now more restrictive. **Quick fix** - Use a type assertion: ```typescript import { GenericEndpointContext } from "better-auth"; const context = await auth.$context; const user = await runWithEndpointContext( { context } as GenericEndpointContext, () => context.internalAdapter.createUser({ email, name, role, invitedBy: invitedBy.id, }), ); ``` **Recommended approach** - Use `auth.api` instead, which doesn't require `runWithEndpointContext`: ```typescript const user = await auth.api.signUpEmail({ body: { email, name, password }, }); ``` The maintainers [discourage using `auth.$context` outside endpoint scope](https://github.com/better-auth/better-auth/issues/6315) and recommend `auth.api` for server-side operations. If you need direct adapter access, the [admin plugin](https://better-auth.com/docs/plugins/admin) provides server-side APIs for user management. <!-- 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/d05f63f4-9fd6-4963-8c14-0af19e741515?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d05f63f4-9fd6-4963-8c14-0af19e741515?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d05f63f4-9fd6-4963-8c14-0af19e741515?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d05f63f4-9fd6-4963-8c14-0af19e741515?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d05f63f4-9fd6-4963-8c14-0af19e741515?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d05f63f4-9fd6-4963-8c14-0af19e741515?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d05f63f4-9fd6-4963-8c14-0af19e741515?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%20type%20error%20is%20caused%20by%20stricter%20type%20checking%20introduced%20in%20v1.5%20via%20%5BPR%20%235359%5D%28https%3A//github.com/better-auth/better-auth/pull/5359%29.%20Your%20code%20pattern%20was%20structurally%20correct%2C%20but%20the%20types%20are%20now%20more%20restrictive.%0A%0A%2A%2AQuick%20fix%2A%2A%20-%20Use%20a%20type%20assertion%3A%0A%0A%60%60%60typescript%0Aimport%20%7B%20GenericEndpointContext%20%7D%20from%20%22better-auth%22%3B%0A%0Aconst%20context%20%3D%20await%20auth.%24context%3B%0Aconst%20user%20%3D%20await%20runWithEndpointContext%28%0A%20%20%7B%20context%20%7D%20as%20GenericEndpointContext%2C%0A%20%20%28%29%20%3D%3E%20context.internalAdapter.createUser%28%7B%0A%20%20%20%20email%2C%0A%20%20%20%20name%2C%0A%20%20%20%20role%2C%0A%20%20%20%20invitedBy%3A%20invitedBy.id%2C%0A%20%20%7D%29%2C%0A%29%3B%0A%60%60%60%0A%0A%2A%2ARecommended%20approach%2A%2A%20-%20Use%20%60auth.api%60%20instead%2C%20which%20doesn%27t%20require%20%60runWithEndpointContext%60%3A%0A%0A%60%60%60typescript%0Aconst%20user%20%3D%20await%20auth.api.signUpEmail%28%7B%0A%20%20body%3A%20%7B%20email%2C%20name%2C%20password%20%7D%2C%0A%7D%29%3B%0A%60%60%60%0A%0AThe%20maintainers%20%5Bdiscourage%20using%20%60auth.%24context%60%20outside%20endpoint%20scope%5D%28https%3A//github.com/better-auth/better-auth/issues/6315%29%20and%20recommend%20%60auth.api%60%20for%20server-side%20operations.%20If%20you%20need%20direct%20adapter%20access%2C%20the%20%5Badmin%20plugin%5D%28https%3A//better-auth.com/docs/plugins/admin%29%20provides%20server-side%20APIs%20for%20user%20management.)&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/8281)
Author
Owner

@himself65 commented on GitHub (Mar 2, 2026):

Yes, as the bot mentioned, it should be like that. And The API is not for user side, It's for the internal API to share the context

@himself65 commented on GitHub (Mar 2, 2026): Yes, as the bot mentioned, it should be like that. And The API is not for user side, It's for the internal API to share the context
Author
Owner

@MrLightful commented on GitHub (Mar 2, 2026):

Small addition to bot's answer. Type to GenericEndpointContext via unknown.

e32bad12ea/packages/better-auth/src/api/routes/session-api.test.ts (L331-L335)

@MrLightful commented on GitHub (Mar 2, 2026): Small addition to bot's answer. Type to `GenericEndpointContext` via `unknown`. https://github.com/better-auth/better-auth/blob/e32bad12eab2745072c80c957b00b49d6ae5ae25/packages/better-auth/src/api/routes/session-api.test.ts#L331-L335
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2958