Inferred type missing after using username plugin #2099

Closed
opened 2026-03-13 09:26:54 -05:00 by GiteaMirror · 9 comments
Owner

Originally created by @aybangueco on GitHub (Oct 10, 2025).

Originally assigned to: @himself65 on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  • Integrate better auth to hono
  • Follow the setup from documentation
  • Use username plugin

Current vs. Expected behavior

I followed the official Hono integration. I used the username plugin on top of that, but when I'm about to get the user and session, I'm expecting the properties of user and session but I got any instead.

Image

What version of Better Auth are you using?

1.3.27

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.0.0: Wed Sep 17 21:41:45 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6000",
    "release": "25.0.0",
    "cpuCount": 8,
    "cpuModel": "Apple M1 Pro",
    "totalMemory": "16.00 GB",
    "freeMemory": "1.35 GB"
  },
  "node": {
    "version": "v22.20.0",
    "env": "development"
  },
  "packageManager": {
    "name": "bun",
    "version": "1.2.23"
  },
  "frameworks": [
    {
      "name": "hono",
      "version": "^4.9.10"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "^8.16.3"
    },
    {
      "name": "drizzle",
      "version": "^0.44.6"
    }
  ],
  "betterAuth": {
    "version": "^1.3.27",
    "config": {
      "emailAndPassword": {
        "enabled": true
      },
      "plugins": [
        {
          "name": "username",
          "config": {
            "id": "username",
            "endpoints": {},
            "schema": {
              "user": {
                "fields": {
                  "username": {
                    "type": "string",
                    "required": false,
                    "sortable": true,
                    "unique": true,
                    "returned": true,
                    "transform": {}
                  },
                  "displayUsername": {
                    "type": "string",
                    "required": false,
                    "transform": {}
                  }
                }
              }
            },
            "hooks": {
              "before": [
                {},
                {}
              ]
            },
            "$ERROR_CODES": {
              "INVALID_USERNAME_OR_PASSWORD": "[REDACTED]",
              "EMAIL_NOT_VERIFIED": "Email not verified",
              "UNEXPECTED_ERROR": "Unexpected error",
              "USERNAME_IS_ALREADY_TAKEN": "Username is already taken. Please try another.",
              "USERNAME_TOO_SHORT": "Username is too short",
              "USERNAME_TOO_LONG": "Username is too long",
              "INVALID_USERNAME": "Username is invalid",
              "INVALID_DISPLAY_USERNAME": "Display username is invalid"
            }
          }
        }
      ],
      "trustedOrigins": [
        "http://localhost:3000"
      ]
    }
  }
}

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

Types

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { username } from "better-auth/plugins";
import db from "@/config/db";
import env from "@/config/env";

export const auth = betterAuth({
	database: drizzleAdapter(db, {
		provider: "pg",
	}),
	emailAndPassword: {
		enabled: true,
	},
	plugins: [
		username({
			minUsernameLength: 4,
			maxUsernameLength: 15,
		}),
	],
	trustedOrigins: [env.FE_URL],
});

Additional context

No response

Originally created by @aybangueco on GitHub (Oct 10, 2025). Originally assigned to: @himself65 on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce - Integrate better auth to hono - Follow the setup from documentation - Use username plugin ### Current vs. Expected behavior I followed the official [Hono](https://www.better-auth.com/docs/integrations/hono#middleware) integration. I used the username plugin on top of that, but when I'm about to get the user and session, I'm expecting the properties of user and session but I got any instead. <img width="457" height="138" alt="Image" src="https://github.com/user-attachments/assets/7f1102b4-b348-41ac-986d-4f89b82fdde4" /> ### What version of Better Auth are you using? 1.3.27 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.0.0: Wed Sep 17 21:41:45 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6000", "release": "25.0.0", "cpuCount": 8, "cpuModel": "Apple M1 Pro", "totalMemory": "16.00 GB", "freeMemory": "1.35 GB" }, "node": { "version": "v22.20.0", "env": "development" }, "packageManager": { "name": "bun", "version": "1.2.23" }, "frameworks": [ { "name": "hono", "version": "^4.9.10" } ], "databases": [ { "name": "pg", "version": "^8.16.3" }, { "name": "drizzle", "version": "^0.44.6" } ], "betterAuth": { "version": "^1.3.27", "config": { "emailAndPassword": { "enabled": true }, "plugins": [ { "name": "username", "config": { "id": "username", "endpoints": {}, "schema": { "user": { "fields": { "username": { "type": "string", "required": false, "sortable": true, "unique": true, "returned": true, "transform": {} }, "displayUsername": { "type": "string", "required": false, "transform": {} } } } }, "hooks": { "before": [ {}, {} ] }, "$ERROR_CODES": { "INVALID_USERNAME_OR_PASSWORD": "[REDACTED]", "EMAIL_NOT_VERIFIED": "Email not verified", "UNEXPECTED_ERROR": "Unexpected error", "USERNAME_IS_ALREADY_TAKEN": "Username is already taken. Please try another.", "USERNAME_TOO_SHORT": "Username is too short", "USERNAME_TOO_LONG": "Username is too long", "INVALID_USERNAME": "Username is invalid", "INVALID_DISPLAY_USERNAME": "Display username is invalid" } } } ], "trustedOrigins": [ "http://localhost:3000" ] } } } ``` ### Which area(s) are affected? (Select all that apply) Types ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { username } from "better-auth/plugins"; import db from "@/config/db"; import env from "@/config/env"; export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", }), emailAndPassword: { enabled: true, }, plugins: [ username({ minUsernameLength: 4, maxUsernameLength: 15, }), ], trustedOrigins: [env.FE_URL], }); ``` ### Additional context _No response_
GiteaMirror added the hono label 2026-03-13 09:26:54 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Oct 10, 2025):

Hi @aybangueco! I'm Dosu and I’m helping the better-auth team.

This is a known TypeScript issue with Better Auth plugins like username. If you see any for user/session types, check your tsconfig.json for "exactOptionalPropertyTypes": true—this flag breaks type inference for plugin fields. Set "exactOptionalPropertyTypes": false to restore proper type inference for fields like username and displayUsername in your session and user types (source).

Also, make sure you use plugins directly in your config (not with type assertions like as unknown as BetterAuthPlugin). Recent updates to Better Auth have improved type inference for plugins and custom sessions, so upgrading may help if you’re not on the latest version (source).

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Oct 10, 2025): <!-- Greeting --> Hi @aybangueco! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known TypeScript issue with Better Auth plugins like `username`. If you see `any` for user/session types, check your `tsconfig.json` for `"exactOptionalPropertyTypes": true`—this flag breaks type inference for plugin fields. Set `"exactOptionalPropertyTypes": false` to restore proper type inference for fields like `username` and `displayUsername` in your session and user types ([source](https://github.com/better-auth/better-auth/issues/5159)). Also, make sure you use plugins directly in your config (not with type assertions like `as unknown as BetterAuthPlugin`). Recent updates to Better Auth have improved type inference for plugins and custom sessions, so upgrading may help if you’re not on the latest version ([source](https://github.com/better-auth/better-auth/pull/4930)). <!-- 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/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&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/5218)
Author
Owner

@aybangueco commented on GitHub (Oct 10, 2025):

Hi @aybangueco! I'm Dosu and I’m helping the better-auth team.

This is a known TypeScript issue with Better Auth plugins like username. If you see any for user/session types, check your tsconfig.json for "exactOptionalPropertyTypes": true—this flag breaks type inference for plugin fields. Set "exactOptionalPropertyTypes": false to restore proper type inference for fields like username and displayUsername in your session and user types (source).

Also, make sure you use plugins directly in your config (not with type assertions like as unknown as BetterAuthPlugin). Recent updates to Better Auth have improved type inference for plugins and custom sessions, so upgrading may help if you’re not on the latest version (source).

To reply, just mention @dosu.

How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other Chat with Dosu Join Discord Share on X

This is my tsconfig for extra context. I also tried replicating the solution from #5159 still no luck

tsconfig:

{
	"compilerOptions": {
		"strict": true,
		"jsx": "react-jsx",
		"jsxImportSource": "hono/jsx",
		"exactOptionalPropertyTypes": false,
		"baseUrl": ".",
		"paths": {
			"@/*": ["./src/*"]
		}
	}
}

@aybangueco commented on GitHub (Oct 10, 2025): > Hi [@aybangueco](https://github.com/aybangueco)! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. > > This is a known TypeScript issue with Better Auth plugins like `username`. If you see `any` for user/session types, check your `tsconfig.json` for `"exactOptionalPropertyTypes": true`—this flag breaks type inference for plugin fields. Set `"exactOptionalPropertyTypes": false` to restore proper type inference for fields like `username` and `displayUsername` in your session and user types ([source](https://github.com/better-auth/better-auth/issues/5159)). > > Also, make sure you use plugins directly in your config (not with type assertions like `as unknown as BetterAuthPlugin`). Recent updates to Better Auth have improved type inference for plugins and custom sessions, so upgrading may help if you’re not on the latest version ([source](https://github.com/better-auth/better-auth/pull/4930)). > > _To reply, just mention [@dosu](https://go.dosu.dev/dosubot)._ > > How did I do? [Good](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/efd72103-b1b5-4411-9c88-cd0703c16f3f?feedback_type=other) [![Chat with Dosu](https://camo.githubusercontent.com/d9ffebb979729c9ef0fc4e3090dbae5b17cabbfec8afe378ada6b81913d6ad8a/68747470733a2f2f646f73752e6465762f646f73752d636861742d62616467652e737667)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github) [![Join Discord](https://camo.githubusercontent.com/d562c2df5e4567ea41d37f1d91a4da0839d8341037045b103b2da268998de17f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6a6f696e2d3538363546323f6c6f676f3d646973636f7264266c6f676f436f6c6f723d7768697465266c6162656c3d)](https://go.dosu.dev/discord-bot) [![Share on X](https://camo.githubusercontent.com/4649f705e2396d6f328dbc8e800a0509c9c17b3b20253b36706c393df124b93d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f582d73686172652d626c61636b)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/5218) This is my tsconfig for extra context. I also tried replicating the solution from #5159 still no luck ### tsconfig: ```json { "compilerOptions": { "strict": true, "jsx": "react-jsx", "jsxImportSource": "hono/jsx", "exactOptionalPropertyTypes": false, "baseUrl": ".", "paths": { "@/*": ["./src/*"] } } } ```
Author
Owner

@dosubot[bot] commented on GitHub (Oct 10, 2025):

You've already set "exactOptionalPropertyTypes": false and are using the plugin directly, which are the main requirements for type inference to work with Better Auth plugins like username 1 2. The plugin system is designed to augment types automatically, and recent versions (including 1.3.27) include fixes for plugin-aware type inference 3.

A few things to double-check:

  • Make sure you are not importing or initializing the plugin in a way that breaks type inference (e.g., no as unknown as BetterAuthPlugin anywhere).
  • Ensure there are no custom type overrides or augmentations elsewhere in your project that could mask the inferred types.
  • Try restarting your TypeScript server or IDE—sometimes stale caches cause inference to break even when config is correct.
  • If you are using project references or a monorepo, make sure all subprojects have compatible TypeScript settings.

If all of the above checks out and you still see any, it could be a subtle interaction with your project setup or a rare edge case. If you can reproduce this in a minimal repo, it would help pinpoint the cause. Recent PRs and tests confirm that the plugin system should work as expected with your config 3.

Let me know if you spot anything unusual in your plugin usage or project structure!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Oct 10, 2025): <!-- Answer --> You've already set `"exactOptionalPropertyTypes": false` and are using the plugin directly, which are the main requirements for type inference to work with Better Auth plugins like `username` [1](https://github.com/better-auth/better-auth/issues/5159) [2](https://github.com/better-auth/better-auth/pull/4930). The plugin system is designed to augment types automatically, and recent versions (including 1.3.27) include fixes for plugin-aware type inference [3](https://github.com/better-auth/better-auth/pull/5009). A few things to double-check: - Make sure you are not importing or initializing the plugin in a way that breaks type inference (e.g., no `as unknown as BetterAuthPlugin` anywhere). - Ensure there are no custom type overrides or augmentations elsewhere in your project that could mask the inferred types. - Try restarting your TypeScript server or IDE—sometimes stale caches cause inference to break even when config is correct. - If you are using project references or a monorepo, make sure all subprojects have compatible TypeScript settings. If all of the above checks out and you still see `any`, it could be a subtle interaction with your project setup or a rare edge case. If you can reproduce this in a minimal repo, it would help pinpoint the cause. Recent PRs and tests confirm that the plugin system should work as expected with your config [3](https://github.com/better-auth/better-auth/pull/5009). Let me know if you spot anything unusual in your plugin usage or project structure! <!-- 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/1a62e879-5ea8-416d-ba52-d08330b4853f?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/1a62e879-5ea8-416d-ba52-d08330b4853f?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/1a62e879-5ea8-416d-ba52-d08330b4853f?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/1a62e879-5ea8-416d-ba52-d08330b4853f?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/1a62e879-5ea8-416d-ba52-d08330b4853f?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/1a62e879-5ea8-416d-ba52-d08330b4853f?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/1a62e879-5ea8-416d-ba52-d08330b4853f?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&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/5218)
Author
Owner

@aybangueco commented on GitHub (Oct 11, 2025):

There should be username and displayname type properties here too but they seemed to be missing as well

Image

Auth config:

export const auth = betterAuth({
	database: drizzleAdapter(db, {
		provider: "pg",
	}),
	emailAndPassword: {
		enabled: true,
	},
	user: {
		additionalFields: {
			username: { type: "string", required: true },
			displayUsername: { type: "string", required: false },
		},
	},
	plugins: [
		username({
			minUsernameLength: 4,
			maxUsernameLength: 15,
		}),
	],
	trustedOrigins: [env.FE_URL],
});
@aybangueco commented on GitHub (Oct 11, 2025): There should be username and displayname type properties here too but they seemed to be missing as well <img width="594" height="270" alt="Image" src="https://github.com/user-attachments/assets/be353e84-35ca-4a6a-9496-9ba08406baeb" /> ### Auth config: ```ts export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", }), emailAndPassword: { enabled: true, }, user: { additionalFields: { username: { type: "string", required: true }, displayUsername: { type: "string", required: false }, }, }, plugins: [ username({ minUsernameLength: 4, maxUsernameLength: 15, }), ], trustedOrigins: [env.FE_URL], }); ```
Author
Owner

@dosubot[bot] commented on GitHub (Oct 11, 2025):

This is a current limitation in Better Auth: while you can define additional fields like username and displayUsername in both user.additionalFields and plugins, full type inference for these fields isn't yet supported. Even with the correct config and the plugin, these properties may not show up in the inferred user/session types. Improved type support for additional fields is planned in future releases (source). For now, you may need to manually augment your types or rely on runtime checks if you need those fields in TypeScript.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Oct 11, 2025): <!-- Answer --> This is a current limitation in Better Auth: while you can define additional fields like `username` and `displayUsername` in both `user.additionalFields` and plugins, full type inference for these fields isn't yet supported. Even with the correct config and the plugin, these properties may not show up in the inferred user/session types. Improved type support for additional fields is planned in future releases ([source](https://github.com/better-auth/better-auth/pull/5146)). For now, you may need to manually augment your types or rely on runtime checks if you need those fields in TypeScript. <!-- 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/b7a44de7-5e87-465f-9137-de47dd29f8f5?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/b7a44de7-5e87-465f-9137-de47dd29f8f5?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/b7a44de7-5e87-465f-9137-de47dd29f8f5?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/b7a44de7-5e87-465f-9137-de47dd29f8f5?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/b7a44de7-5e87-465f-9137-de47dd29f8f5?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/b7a44de7-5e87-465f-9137-de47dd29f8f5?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/b7a44de7-5e87-465f-9137-de47dd29f8f5?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&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/5218)
Author
Owner

@aybangueco commented on GitHub (Oct 11, 2025):

As of now I came up with this solution instead. I used drizzle-zod to generate schemas from drizzle orm schema tables. Not a great solution but it works for me.

export const user = pgTable("user", {
	id: text("id").primaryKey(),
	name: text("name").notNull(),
	email: text("email").notNull().unique(),
	emailVerified: boolean("email_verified").default(false).notNull(),
	image: text("image"),
	createdAt: timestamp("created_at").defaultNow().notNull(),
	updatedAt: timestamp("updated_at")
		.defaultNow()
		.$onUpdate(() => /* @__PURE__ */ new Date())
		.notNull(),
	username: text("username").unique(),
	displayUsername: text("display_username"),
});

const userSelectSchema = createSelectSchema(user);
export type User = z.infer<typeof userSelectSchema>;

export const session = pgTable("session", {
	id: text("id").primaryKey(),
	expiresAt: timestamp("expires_at").notNull(),
	token: text("token").notNull().unique(),
	createdAt: timestamp("created_at").defaultNow().notNull(),
	updatedAt: timestamp("updated_at")
		.$onUpdate(() => /* @__PURE__ */ new Date())
		.notNull(),
	ipAddress: text("ip_address"),
	userAgent: text("user_agent"),
	userId: text("user_id")
		.notNull()
		.references(() => user.id, { onDelete: "cascade" }),
});

const sessionSelectSchema = createSelectSchema(session);
export type Session = z.infer<typeof sessionSelectSchema>;

Inferred types from zod:

export type AppBindings = {
	Variables: {
		user: User | null;
		session: Session | null;
	};
};

Result:

Image
@aybangueco commented on GitHub (Oct 11, 2025): As of now I came up with this solution instead. I used [drizzle-zod](https://orm.drizzle.team/docs/zod) to generate schemas from drizzle orm schema tables. Not a great solution but it works for me. ```ts export const user = pgTable("user", { id: text("id").primaryKey(), name: text("name").notNull(), email: text("email").notNull().unique(), emailVerified: boolean("email_verified").default(false).notNull(), image: text("image"), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at") .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), username: text("username").unique(), displayUsername: text("display_username"), }); const userSelectSchema = createSelectSchema(user); export type User = z.infer<typeof userSelectSchema>; export const session = pgTable("session", { id: text("id").primaryKey(), expiresAt: timestamp("expires_at").notNull(), token: text("token").notNull().unique(), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at") .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), ipAddress: text("ip_address"), userAgent: text("user_agent"), userId: text("user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), }); const sessionSelectSchema = createSelectSchema(session); export type Session = z.infer<typeof sessionSelectSchema>; ``` ### Inferred types from zod: ```ts export type AppBindings = { Variables: { user: User | null; session: Session | null; }; }; ``` ### Result: <img width="482" height="297" alt="Image" src="https://github.com/user-attachments/assets/eb931f27-0623-42f7-8819-431ce83b86bb" />
Author
Owner

@himself65 commented on GitHub (Oct 20, 2025):

I think I've fixed this today. Let me add a test for this.

@himself65 commented on GitHub (Oct 20, 2025): I think I've fixed this today. Let me add a test for this.
Author
Owner

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

I see the test case has been merged.
Hello @aybangueco can you confirm this is still an issue?

@ping-maxwell commented on GitHub (Jan 9, 2026): I see the test case has been merged. Hello @aybangueco can you confirm this is still an issue?
Author
Owner

@aybangueco commented on GitHub (Feb 9, 2026):

I see the test case has been merged. Hello @aybangueco can you confirm this is still an issue?

It is working fine on my end, so I guess can close this now.

@aybangueco commented on GitHub (Feb 9, 2026): > I see the test case has been merged. Hello [@aybangueco](https://github.com/aybangueco) can you confirm this is still an issue? It is working fine on my end, so I guess can close this now.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2099