[GH-ISSUE #2789] The inferred type of this node exceeds the maximum length the compiler will serialize #26672

Closed
opened 2026-04-17 17:19:25 -05:00 by GiteaMirror · 16 comments
Owner

Originally created by @SooditK on GitHub (May 25, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/2789

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

I am using Hono as my backend and Tanstack Router (Vite) as my frontend, I created the attached auth.ts and it is throwing the following error:

The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.

It only happens when I add the organization plugin:

import { betterAuth } from "better-auth"
import { organization } from "better-auth/plugins"
 
export const auth = betterAuth({
    plugins: [
        // other plugins
        organization() 
    ],
    // other stuff like database & providers
})
Here's my tsconfig.json
{
	"compilerOptions": {
		"composite": true,
		"target": "ESNext",
		"module": "ESNext",
		"moduleResolution": "bundler",
		"verbatimModuleSyntax": true,
		"strict": true,
		"skipLibCheck": true,
		"baseUrl": "./",
		"paths": {
			"@/*": ["./src/*"]
		},
		"outDir": "./dist",
		"types": ["bun"],
		"jsx": "react-jsx",
		"jsxImportSource": "hono/jsx"
	},
	"tsc-alias": {
		"resolveFullPaths": true
	}
}

The steps to reproduce are very simple, create a Hono app and add the attached auth.ts file with organization plugin

Current vs. Expected behavior

No type errors 🤷🏼

What version of Better Auth are you using?

1.2.8

Provide environment information

OS: macOS 15.4 24E248 arm64
Host: Mac14,3
CPU: Apple M2

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

Backend

Auth config (if applicable)

import { db } from "@/db"; // your drizzle instance
import { env } from "@/middlewares/env";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { admin, organization, twoFactor } from "better-auth/plugins";
import { captcha } from "better-auth/plugins";
import { openAPI } from "better-auth/plugins";
import { stripe } from "@better-auth/stripe";
import { emailHarmony } from "better-auth-harmony";
import { stripeClient } from "@/lib/stripe";

export const auth = betterAuth({
	appName: "My App",
	plugins: [
		twoFactor(),
		admin(),
		organization(), // <------ THIS IS WHAT IS CAUSING THE WHOLE ERROR, IF YOU COMMENT IT EVERYTHING WORKS FINE
		captcha({
			provider: "cloudflare-turnstile",
			secretKey: env.TURNSTILE_SECRET_KEY,
		}),
		openAPI(),
		stripe({
			stripeClient,
			stripeWebhookSecret: env.STRIPE_WEBHOOK_SECRET,
			createCustomerOnSignUp: true,
		}),
		emailHarmony(),
	],
	database: drizzleAdapter(db, {
		provider: "pg",
	}),
	emailAndPassword: {
		enabled: true,
	},
	socialProviders: {
		google: {
			clientId: env.GOOGLE_CLIENT_ID,
			clientSecret: env.GOOGLE_CLIENT_SECRET,
		},
	},
});

Additional context

No response

Originally created by @SooditK on GitHub (May 25, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/2789 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce I am using `Hono` as my backend and `Tanstack Router (Vite)` as my frontend, I created the attached `auth.ts` and it is throwing the following error: `The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.` It only happens when I add the `organization` plugin: ```ts import { betterAuth } from "better-auth" import { organization } from "better-auth/plugins" export const auth = betterAuth({ plugins: [ // other plugins organization() ], // other stuff like database & providers }) ``` <details><summary>Here's my tsconfig.json</summary> ```json { "compilerOptions": { "composite": true, "target": "ESNext", "module": "ESNext", "moduleResolution": "bundler", "verbatimModuleSyntax": true, "strict": true, "skipLibCheck": true, "baseUrl": "./", "paths": { "@/*": ["./src/*"] }, "outDir": "./dist", "types": ["bun"], "jsx": "react-jsx", "jsxImportSource": "hono/jsx" }, "tsc-alias": { "resolveFullPaths": true } } ``` </details> The steps to reproduce are very simple, create a `Hono` app and add the attached `auth.ts` file with `organization` plugin ### Current vs. Expected behavior No type errors 🤷🏼 ### What version of Better Auth are you using? 1.2.8 ### Provide environment information ```bash OS: macOS 15.4 24E248 arm64 Host: Mac14,3 CPU: Apple M2 ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { db } from "@/db"; // your drizzle instance import { env } from "@/middlewares/env"; import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { admin, organization, twoFactor } from "better-auth/plugins"; import { captcha } from "better-auth/plugins"; import { openAPI } from "better-auth/plugins"; import { stripe } from "@better-auth/stripe"; import { emailHarmony } from "better-auth-harmony"; import { stripeClient } from "@/lib/stripe"; export const auth = betterAuth({ appName: "My App", plugins: [ twoFactor(), admin(), organization(), // <------ THIS IS WHAT IS CAUSING THE WHOLE ERROR, IF YOU COMMENT IT EVERYTHING WORKS FINE captcha({ provider: "cloudflare-turnstile", secretKey: env.TURNSTILE_SECRET_KEY, }), openAPI(), stripe({ stripeClient, stripeWebhookSecret: env.STRIPE_WEBHOOK_SECRET, createCustomerOnSignUp: true, }), emailHarmony(), ], database: drizzleAdapter(db, { provider: "pg", }), emailAndPassword: { enabled: true, }, socialProviders: { google: { clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, }, }, }); ``` ### Additional context _No response_
GiteaMirror added the locked label 2026-04-17 17:19:25 -05:00
Author
Owner

@Kinfe123 commented on GitHub (May 28, 2025):

can you please update your tsconfig to the snippet below figure out the source of the casue -

{
  "compilerOptions": {
    "composite": true,
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "verbatimModuleSyntax": true,
    "strict": true,
    "skipLibCheck": true,
    "baseUrl": "./",
    "paths": {
      "@/*": ["./src/*"]
    },
    "outDir": "./dist",
    "types": ["bun"],
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx",
    "maxNodeModuleJsSize": 1000000,
    "typeRoots": ["./node_modules/@types"],
    "incremental": true,
    "isolatedModules": true
  },
  "tsc-alias": {
    "resolveFullPaths": true
  }
}
<!-- gh-comment-id:2914598300 --> @Kinfe123 commented on GitHub (May 28, 2025): can you please update your tsconfig to the snippet below figure out the source of the casue - ```json { "compilerOptions": { "composite": true, "target": "ESNext", "module": "ESNext", "moduleResolution": "bundler", "verbatimModuleSyntax": true, "strict": true, "skipLibCheck": true, "baseUrl": "./", "paths": { "@/*": ["./src/*"] }, "outDir": "./dist", "types": ["bun"], "jsx": "react-jsx", "jsxImportSource": "hono/jsx", "maxNodeModuleJsSize": 1000000, "typeRoots": ["./node_modules/@types"], "incremental": true, "isolatedModules": true }, "tsc-alias": { "resolveFullPaths": true } } ```
Author
Owner

@joel611 commented on GitHub (May 29, 2025):

try add these 2 lines to tsconfig.json

"compilerOptions": {
    "declaration": false,
    "declarationMap": false,
    ...
},
<!-- gh-comment-id:2919756408 --> @joel611 commented on GitHub (May 29, 2025): try add these 2 lines to tsconfig.json ```json "compilerOptions": { "declaration": false, "declarationMap": false, ... }, ```
Author
Owner

@Kinfe123 commented on GitHub (May 29, 2025):

if those values are set on the tsconfig it makes it hard for having the types and types map work.

<!-- gh-comment-id:2919939255 --> @Kinfe123 commented on GitHub (May 29, 2025): if those values are set on the tsconfig it makes it hard for having the types and types map work.
Author
Owner

@tunctn commented on GitHub (Jun 1, 2025):

you can try the following approach:

const authConfig = {
  database: drizzleAdapter(db, {
    provider: "pg",
  }),
  // rest of your config
} satisfies Parameters<typeof betterAuth>[0];

export const auth: ReturnType<typeof betterAuth<typeof authConfig>> = betterAuth(authConfig);

however, there’s one issue when using custom field mappings in the table definition. for some reason, ts doesn’t recognize id as a valid field in the models (users, sessions, etc). for example:

user: {
  modelName: "users",
  fields: {
    id: "id",
    name: "full_name",
    email: "email",
    emailVerified: "email_verified",
    image: "image",
    createdAt: "created_at",
    updatedAt: "updated_at",
  }
}

this throws the following ts error:
Object literal may only specify known properties, and id does not exist in type Partial<Record<"createdAt" | "updatedAt" | "email" | "name" | "emailVerified" | "image", string>>.ts(2353)

as a workaround, I simply suppressed the error with @ts-expect-error on the id field:

user: {
  modelName: "users",
  fields: {
    // @ts-expect-error
    id: "id",
    name: "full_name",
    email: "email",
    emailVerified: "email_verified",
    image: "image",
    createdAt: "created_at",
    updatedAt: "updated_at",
  }
}

it's not ideal, but this did resolve the issue for me.

for the record, my tsconfig.json:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": ["@tsconfig/recommended/tsconfig.json", "@tsconfig/node22/tsconfig.json"],
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictBindCallApply": true,
    "strictFunctionTypes": true,
    "strictNullChecks": true,
    "strictPropertyInitialization": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitOverride": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "useUnknownInCatchVariables": true,
    "noUncheckedIndexedAccess": true,
    "noPropertyAccessFromIndexSignature": true,
    "verbatimModuleSyntax": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "useDefineForClassFields": true,
    "resolveJsonModule": true,
    "removeComments": true,
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "declaration": true,
    "declarationMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
    },
    "outDir": "./dist"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

and package.json

 "devDependencies": {
    "@types/node": "^22.15.29",
    "typescript": "^5.8.3",
    // rest of the packages
  }
<!-- gh-comment-id:2927756721 --> @tunctn commented on GitHub (Jun 1, 2025): you can try the following approach: ```ts const authConfig = { database: drizzleAdapter(db, { provider: "pg", }), // rest of your config } satisfies Parameters<typeof betterAuth>[0]; export const auth: ReturnType<typeof betterAuth<typeof authConfig>> = betterAuth(authConfig); ``` however, there’s one issue when using custom field mappings in the table definition. for some reason, ts doesn’t recognize `id` as a valid field in the models (users, sessions, etc). for example: ```ts user: { modelName: "users", fields: { id: "id", name: "full_name", email: "email", emailVerified: "email_verified", image: "image", createdAt: "created_at", updatedAt: "updated_at", } } ``` this throws the following ts error: `Object literal may only specify known properties, and id does not exist in type Partial<Record<"createdAt" | "updatedAt" | "email" | "name" | "emailVerified" | "image", string>>.ts(2353)` as a workaround, I simply suppressed the error with @ts-expect-error on the `id` field: ```ts user: { modelName: "users", fields: { // @ts-expect-error id: "id", name: "full_name", email: "email", emailVerified: "email_verified", image: "image", createdAt: "created_at", updatedAt: "updated_at", } } ``` it's not ideal, but this did resolve the issue for me. for the record, my tsconfig.json: ```json { "$schema": "https://json.schemastore.org/tsconfig", "extends": ["@tsconfig/recommended/tsconfig.json", "@tsconfig/node22/tsconfig.json"], "compilerOptions": { "strict": true, "noImplicitAny": true, "noImplicitThis": true, "strictBindCallApply": true, "strictFunctionTypes": true, "strictNullChecks": true, "strictPropertyInitialization": true, "noFallthroughCasesInSwitch": true, "noImplicitOverride": true, "noImplicitReturns": true, "noUnusedLocals": true, "noUnusedParameters": true, "useUnknownInCatchVariables": true, "noUncheckedIndexedAccess": true, "noPropertyAccessFromIndexSignature": true, "verbatimModuleSyntax": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "skipLibCheck": true, "useDefineForClassFields": true, "resolveJsonModule": true, "removeComments": true, "target": "ES2022", "module": "ESNext", "moduleResolution": "Bundler", "declaration": true, "declarationMap": true, "baseUrl": ".", "paths": { "@/*": ["./src/*"], }, "outDir": "./dist" }, "include": ["src/**/*"], "exclude": ["node_modules"] } ``` and package.json ```ts "devDependencies": { "@types/node": "^22.15.29", "typescript": "^5.8.3", // rest of the packages } ```
Author
Owner

@Kinfe123 commented on GitHub (Jun 7, 2025):

I'm closing this now but make sure to tag me if this is still an issue.

<!-- gh-comment-id:2953204326 --> @Kinfe123 commented on GitHub (Jun 7, 2025): I'm closing this now but make sure to tag me if this is still an issue.
Author
Owner

@jpainam commented on GitHub (Jun 13, 2025):

I have the issue after adding admin(), the compileOptions didn't work

import type { BetterAuthOptions } from "better-auth";
import { expo } from "@better-auth/expo";
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { nextCookies } from "better-auth/next-js";
import { admin, apiKey, oAuthProxy, username } from "better-auth/plugins";

import { db } from "@repo/db";
import { sendEmail } from "@repo/utils";

export function initAuth(options: {
  baseUrl: string;
  productionUrl: string;
  secret: string | undefined;
}) {
  const config = {
    database: prismaAdapter(db, {
      provider: "postgresql",
    }),
    user: {
    baseURL: options.baseUrl,
    secret: options.secret,
    },
    plugins: [
      admin(),
      username(),
      apiKey({
        enableMetadata: true,
      }),
      nextCookies(),
    ],
    trustedOrigins: ["expo://"],
  } satisfies BetterAuthOptions;

  return betterAuth(config);
}
export type Auth = ReturnType<typeof initAuth>;
export type Session = Auth["$Infer"]["Session"];

<!-- gh-comment-id:2968849717 --> @jpainam commented on GitHub (Jun 13, 2025): I have the issue after adding `admin()`, the `compileOptions` didn't work ```tsx import type { BetterAuthOptions } from "better-auth"; import { expo } from "@better-auth/expo"; import { betterAuth } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import { nextCookies } from "better-auth/next-js"; import { admin, apiKey, oAuthProxy, username } from "better-auth/plugins"; import { db } from "@repo/db"; import { sendEmail } from "@repo/utils"; export function initAuth(options: { baseUrl: string; productionUrl: string; secret: string | undefined; }) { const config = { database: prismaAdapter(db, { provider: "postgresql", }), user: { baseURL: options.baseUrl, secret: options.secret, }, plugins: [ admin(), username(), apiKey({ enableMetadata: true, }), nextCookies(), ], trustedOrigins: ["expo://"], } satisfies BetterAuthOptions; return betterAuth(config); } export type Auth = ReturnType<typeof initAuth>; export type Session = Auth["$Infer"]["Session"]; ```
Author
Owner

@Kinfe123 commented on GitHub (Jun 13, 2025):

For now, setting declaration: false seems to be working, but we’ll look into it further.

<!-- gh-comment-id:2968861427 --> @Kinfe123 commented on GitHub (Jun 13, 2025): For now, setting `declaration: false` seems to be working, but we’ll look into it further.
Author
Owner

@jpainam commented on GitHub (Jun 13, 2025):

Option 'declarationMap' cannot be specified without specifying option 'declaration' or option 'composite'.ts
Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration' or option 'composite'.ts
⚠ Error

Option declarationMap cannot be specified without specifying option declaration or option composite .
⚠ Error

Option emitDeclarationOnly cannot be specified without specifying option declaration or option composite .
Generate .d.ts files from TypeScript and JavaScript files in your project.

See more: [https://www.typescriptlang.org/tsconfig#declaration](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html)

based on my monorepo settings, i need declaration:true, i'm using this. https://github.com/t3-oss/create-t3-turbo/tree/main

<!-- gh-comment-id:2968869723 --> @jpainam commented on GitHub (Jun 13, 2025): ```tsx Option 'declarationMap' cannot be specified without specifying option 'declaration' or option 'composite'.ts Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration' or option 'composite'.ts ⚠ Error Option declarationMap cannot be specified without specifying option declaration or option composite . ⚠ Error Option emitDeclarationOnly cannot be specified without specifying option declaration or option composite . Generate .d.ts files from TypeScript and JavaScript files in your project. See more: [https://www.typescriptlang.org/tsconfig#declaration](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html) ``` based on my `monorepo` settings, i need `declaration:true`, i'm using this. https://github.com/t3-oss/create-t3-turbo/tree/main
Author
Owner

@Kinfe123 commented on GitHub (Jun 13, 2025):

can you please share the tsconfig.json ?

<!-- gh-comment-id:2968877980 --> @Kinfe123 commented on GitHub (Jun 13, 2025): can you please share the tsconfig.json ?
Author
Owner

@jpainam commented on GitHub (Jun 13, 2025):

in my packages/api

{
  "extends": "@repo/typescript-config/internal-package.json",
  "include": ["src"],
  "exclude": ["node_modules"],
  "compilerOptions": {
    "declaration": false
  }
}

my internal-package.json

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "./base.json",
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true,
    "emitDeclarationOnly": true,
    "noEmit": false,
    "outDir": "${configDir}/dist"
  }
}

my base.json

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "compilerOptions": {
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "ES2022",
    "lib": [
      "ES2022"
    ],
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,
    "incremental": true,
    "disableSourceOfProjectReferenceRedirect": true,
    "tsBuildInfoFile": "${configDir}/.cache/tsbuildinfo.json",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "checkJs": true,
    "module": "Preserve",
    "moduleResolution": "Bundler",
    "noEmit": true
  },
  "exclude": [
    "node_modules",
    "build",
    "dist",
    ".next",
    ".expo"
  ]
}

Image

<!-- gh-comment-id:2968887762 --> @jpainam commented on GitHub (Jun 13, 2025): in my `packages/api` ```tsx { "extends": "@repo/typescript-config/internal-package.json", "include": ["src"], "exclude": ["node_modules"], "compilerOptions": { "declaration": false } } ``` my `internal-package.json` ```tsx { "$schema": "https://json.schemastore.org/tsconfig", "extends": "./base.json", "compilerOptions": { "declaration": true, "declarationMap": true, "emitDeclarationOnly": true, "noEmit": false, "outDir": "${configDir}/dist" } } ``` my `base.json` ```tsx { "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "esModuleInterop": true, "skipLibCheck": true, "target": "ES2022", "lib": [ "ES2022" ], "allowJs": true, "resolveJsonModule": true, "moduleDetection": "force", "isolatedModules": true, "incremental": true, "disableSourceOfProjectReferenceRedirect": true, "tsBuildInfoFile": "${configDir}/.cache/tsbuildinfo.json", "strict": true, "noUncheckedIndexedAccess": true, "checkJs": true, "module": "Preserve", "moduleResolution": "Bundler", "noEmit": true }, "exclude": [ "node_modules", "build", "dist", ".next", ".expo" ] } ``` ![Image](https://github.com/user-attachments/assets/9d7102e1-986d-4d98-b6e0-bb1097a8fa31)
Author
Owner

@Kinfe123 commented on GitHub (Jun 13, 2025):

declarationMap and emitDeclarationOnly are still set to true in your base config—and they require declaration: true or composite: true to work.

<!-- gh-comment-id:2968905949 --> @Kinfe123 commented on GitHub (Jun 13, 2025): `declarationMap` and `emitDeclarationOnly` are still set to true in your base config—and they require declaration: true or composite: true to work.
Author
Owner

@Kinfe123 commented on GitHub (Jun 13, 2025):

what about asserting the plugin
admin() as unknown as BetterAuthPlugin

does this works here ?

<!-- gh-comment-id:2968907839 --> @Kinfe123 commented on GitHub (Jun 13, 2025): what about asserting the plugin `admin() as unknown as BetterAuthPlugin` does this works here ?
Author
Owner

@jpainam commented on GitHub (Jun 13, 2025):

admin() as unknown as BetterAuthPlugin is working.

<!-- gh-comment-id:2968923176 --> @jpainam commented on GitHub (Jun 13, 2025): `admin() as unknown as BetterAuthPlugin` is working.
Author
Owner

@stewones commented on GitHub (Jun 26, 2025):

admin() as unknown as BetterAuthPlugin is working.

the problem with this approach is that we lose the type inference

changing ts config is not an option

<!-- gh-comment-id:3008794161 --> @stewones commented on GitHub (Jun 26, 2025): > `admin() as unknown as BetterAuthPlugin` is working. the problem with this approach is that we lose the type inference changing ts config is not an option
Author
Owner

@hammer-ai commented on GitHub (Jun 26, 2025):

Hi @jpainam did you use BetterAuth in an Electron app? Any special things you needed to do, or tips as I look into it?

<!-- gh-comment-id:3009405149 --> @hammer-ai commented on GitHub (Jun 26, 2025): Hi @jpainam did you use BetterAuth in an Electron app? Any special things you needed to do, or tips as I look into it?
Author
Owner

@rohovskoi commented on GitHub (Oct 2, 2025):

@Kinfe123 facing this issue too... I think this issue should be opened again. When I had 5 plugins added, it was fine.. However, when i added 6th one i got this error:
The inferred type of this node exceeds the maximum length the compiler will serialize

Also I cannot solve it with disabling declarations, and composite as I use TS project references...

<!-- gh-comment-id:3362226125 --> @rohovskoi commented on GitHub (Oct 2, 2025): @Kinfe123 facing this issue too... I think this issue should be opened again. When I had 5 plugins added, it was fine.. However, when i added 6th one i got this error: **The inferred type of this node exceeds the maximum length the compiler will serialize** Also I cannot solve it with disabling declarations, and composite as I use TS project references...
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#26672