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

Closed
opened 2026-04-13 04:46:59 -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-13 04:46:59 -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#9349