I've been having a hard time and a lot of different errors trying to set up better-auth in general, but my current struggles are with the Zenstack better-auth adapter. There seem to be type conflicts between the database client created by ZenStack and what the adapter is expecting as its first argument. Before it was complaining about attributes on the schema, but that no longer seems to be the case. So, now I'm back to type conflicts.
Below is the relevant portion of my auth.ts file and the massive TS error I'm getting. I am also getting the "Type instantiation is excessively deep and possibly infinite" error I see complained about a lot with better-auth, but the below error is the one coming up in my build logs.
The Error
import { db } from "@lorewright/db"; // My Zenstack Client
import { zenstackAdapter } from "@zenstackhq/better-auth";
import { betterAuth } from "better-auth/minimal";
import { organization } from "better-auth/plugins";
const zenstack = zenstackAdapter(db, {
provider: "postgresql"
});
...
src/auth.ts(6,34): error TS2345: Argument of type 'ClientContract<SchemaType, { dialect: PostgresDialect; }>' is not assignable to parameter of type 'ClientContract<SchemaType>'.
Type 'ClientContract<SchemaType, { dialect: PostgresDialect; }>' is not assignable to type '{ readonly $schema: SchemaType; readonly $options: { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; ... 5 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }; ... 16 more ...; $pushSchema(): Promise<...>; }'.
The types returned by '$executeRaw(...)' are incompatible between these types.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZenStackPromise<import("/home/.../packages/db/src/zen/schema").SchemaType, number>' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZenStackPromise<import("/home/.../packages/db/src/zen/schema").SchemaType, number>'.
Type 'ZenStackPromise<SchemaType, number>' is not assignable to type '{ cb: (txClient?: ClientContract<SchemaType, { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; plugins?: RuntimePlugin<...>[] | undefined; ... 4 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }> | undefined) => Promise<...>; }'.
Types of property 'cb' are incompatible.
Type '(txClient?: import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28...' is not assignable to type '(txClient?: import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28...'.
Types of parameters 'txClient' and 'txClient' are incompatible.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28.9/node_modu...' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28.9/node_modu...'.
Type 'ClientContract<SchemaType, { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; plugins?: RuntimePlugin<...>[] | undefined; ... 4 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }>' is not assignable to type 'ClientContract<SchemaType, { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; plugins?: RuntimePlugin<...>[] | undefined; ... 4 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }> | undefined'.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28.9/node_modu...' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28.9/node_modu...'.
Type 'ClientContract<SchemaType, { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; plugins?: RuntimePlugin<...>[] | undefined; ... 4 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }>' is not assignable to type '{ readonly $schema: SchemaType; readonly $options: { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; ... 5 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }; ... 16 more ...; $pushSchema(): Promise<...>; }'.
The types of '$options.functions' are incompatible between these types.
Type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>> | undefined' is not assignable to type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>> | undefined'.
Type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>>' is not assignable to type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>>'.
'string' index signatures are incompatible.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>'.
Types of parameters 'context' and 'context' are incompatible.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunctionContext<import("/home/.../packages/db/src/zen/schema").SchemaType>' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunctionContext<import("/home/.../packages/db/src/zen/schema").SchemaType>'.
Types of property 'client' are incompatible.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28.9/node_modu...' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ClientContract<import("/home/.../packages/db/src/zen/schema").SchemaType, { dialect: import("/home/.../node_modules/.pnpm/kysely@0.28.9/node_modu...'.
Type 'ClientContract<SchemaType, { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; plugins?: RuntimePlugin<...>[] | undefined; ... 4 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }>' is not assignable to type '{ readonly $schema: SchemaType; readonly $options: { dialect: Dialect; functions?: Record<string, ZModelFunction<SchemaType>> | undefined; ... 5 more ...; allowQueryTimeOmitOverride?: boolean | undefined; }; ... 16 more ...; $pushSchema(): Promise<...>; }'.
The types of '$options.functions' are incompatible between these types.
Type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>> | undefined' is not assignable to type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>> | undefined'.
Type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>>' is not assignable to type 'Record<string, import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>>'.
'string' index signatures are incompatible.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunction<import("/home/.../packages/db/src/zen/schema").SchemaType>'.
Types of parameters 'context' and 'context' are incompatible.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunctionContext<import("/home/.../packages/db/src/zen/schema").SchemaType>' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").ZModelFunctionContext<import("/home/.../packages/db/src/zen/schema").SchemaType>'.
Types of property 'dialect' are incompatible.
Type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.34_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").BaseCrudDialect<import("/home/.../packages/db/src/zen/schema").SchemaType>' is not assignable to type 'import("/home/.../node_modules/.pnpm/@zenstackhq+orm@3.0.0-beta.33_pg@8.16.3_zod@4.1.13/node_modules/@zenstackhq/orm/dist/index").BaseCrudDialect<import("/home/.../packages/db/src/zen/schema").SchemaType>'.
Property 'schema' is protected but type 'BaseCrudDialect<Schema>' is not a class derived from 'BaseCrudDialect<Schema>'.
My Setup
I am using a monorepo setup with PNPM. I have separate packages with my zenstack v3 schemas and client, as well as one for TypeScript. Here is what i hope is relevant:
ZenStack Version 3.0.0-beta.33
better-auth version 1.4.5
TypeScript Version 5.9.3
Kysely Version 0.28.9
// tsconfig.sjon (combined extended files)
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"allowJs": false,
"allowUnreachableCode": false,
"declaration": false,
"declarationMap": false,
"esModuleInterop": true,
"incremental": false,
"isolatedModules": true,
"lib": [
"es2022",
"DOM",
"DOM.Iterable"
],
"module": "esnext",
"moduleDetection": "force",
"moduleResolution": "bundler",
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noUncheckedSideEffectImports": true,
"resolveJsonModule": true,
"skipLibCheck": ftrue,
"strict": true,
"target": "ES2022"
},
"exclude": [
"node_modules",
"dist"
]
}
// client.ts
import type { ClientContract } from "@zenstackhq/orm";
import { ZenStackClient } from "@zenstackhq/orm";
import { PolicyPlugin } from "@zenstackhq/plugin-policy";
import { PostgresDialect } from "kysely";
import { Pool } from "pg";
import { schema } from "./zen/schema";
export const db = new ZenStackClient(schema, {
dialect: new PostgresDialect({
pool: new Pool({
connectionString: process.env.DATABASE_URL,
}),
}),
});
export const authDb = db.$use(new PolicyPlugin());
export type Db = ClientContract<typeof db.$schema, typeof db.$options>;
Any suggestions for possible workarounds would be appreciated. I'm beginning to suspect I need to opt out of type checking for better-auth entirely, but obviously that's not an attractive option.
I've been having a hard time and a lot of different errors trying to set up better-auth in general, but my current struggles are with the Zenstack better-auth adapter. There seem to be type conflicts between the database client created by ZenStack and what the adapter is expecting as its first argument. Before it was complaining about attributes on the schema, but that no longer seems to be the case. So, now I'm back to type conflicts.
Below is the relevant portion of my auth.ts file and the massive TS error I'm getting. I am also getting the "Type instantiation is excessively deep and possibly infinite" error I see complained about a lot with better-auth, but the below error is the one coming up in my build logs.
The Error
My Setup
I am using a monorepo setup with PNPM. I have separate packages with my zenstack v3 schemas and client, as well as one for TypeScript. Here is what i hope is relevant:
ZenStack Version 3.0.0-beta.33
better-auth version 1.4.5
TypeScript Version 5.9.3
Kysely Version 0.28.9
Any suggestions for possible workarounds would be appreciated. I'm beginning to suspect I need to opt out of type checking for better-auth entirely, but obviously that's not an attractive option.