ERROR [Better Auth]: Failed to create user TypeError: value.toISOString is not a function #1017

Closed
opened 2026-03-13 08:18:00 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @knnedy on GitHub (Apr 9, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

To Reproduce

  1. Create a default nextjs project with (my version is v15.2.4):
npx create-next-app@latest
  1. Install drizzle-orm packages also the postgres packages.
  2. Install better-auth (my version is v1.2.5).
  3. Create a login system(routes and auth_client) using better-auth.
  4. Use signUp.email to signup and create the user.
  5. ERROR on the terminal: [Better Auth]: Failed to create user TypeError: value.toISOString is not a function

Current vs. Expected behavior

Issue #1035 was closed without the soultion but I am not sure its the same issue.

Error On the terminal:

ERROR [Better Auth]: Failed to create user TypeError: value.toISOString is not a function
    at Array.map (<anonymous>)
    at Array.map (<anonymous>)
    at Array.map (<anonymous>)
 POST /api/auth/sign-up/email 422 in 1358ms

What version of Better Auth are you using?

1.2.5

Provide environment information

- Framework: Next.js
- Database adapter: Drizzle
- Database: postgres
- OS: Linux Ubuntu x86_64

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

Backend

Auth config (if applicable)

import db from "@/database/db";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { nextCookies } from "better-auth/next-js";

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
    usePlural: true,
  }),
  emailAndPassword: {
    enabled: true,
  },
  advanced: {
    generateId: false,
  },
  plugins: [nextCookies()],
});

Additional context

auth.ts:

import db from "@/database/db";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { nextCookies } from "better-auth/next-js";

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
    usePlural: true,
  }),
  emailAndPassword: {
    enabled: true,
  },
  advanced: {
    generateId: false,
  },
  plugins: [nextCookies()],
});

db schema:

import {
  timestamp,
  pgTable,
  text,
  integer,
  boolean,
  serial,
} from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
import {
  Label,
  MembershipRequestStatus,
  Priority,
  ProjectRole,
  ProjectStatus,
  Status,
} from "@/lib/config";

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: text("name").notNull(),
  email: text("email").unique().notNull(),
  emailVerified: timestamp("email_verified", { mode: "date", precision: 3 }),
  image: text("image"),
  createdAt: timestamp("created_at", { mode: "date", precision: 3 })
    .defaultNow()
    .notNull(),
  updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate(
    () => new Date()
  ),
});

export const accounts = pgTable("accounts", {
  id: serial("id").primaryKey(),
  accountId: text("account_id").notNull(),
  providerId: text("provider_id").notNull(),
  userId: integer("user_id")
    .notNull()
    .references(() => users.id),
  accessToken: text("access_token"),
  refreshToken: text("refresh_token"),
  idToken: text("id_token"),
  accessTokenExpiresAt: timestamp("access_token_expires_at"),
  refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
  scope: text("scope"),
  password: text("password"),
  createdAt: timestamp("created_at").notNull(),
  updatedAt: timestamp("updated_at").notNull(),
});

export const sessions = pgTable("sessions", {
  id: serial("id").primaryKey(),
  expiresAt: timestamp("expires_at").notNull(),
  token: text("token").notNull().unique(),
  createdAt: timestamp("created_at").notNull(),
  updatedAt: timestamp("updated_at").notNull(),
  ipAddress: text("ip_address"),
  userAgent: text("user_agent"),
  userId: integer("user_id")
    .notNull()
    .references(() => users.id),
});

export const verifications = pgTable("verifications", {
  id: serial("id").primaryKey(),
  identifier: text("identifier").notNull(),
  value: text("value").notNull(),
  expiresAt: timestamp("expires_at").notNull(),
  createdAt: timestamp("created_at"),
  updatedAt: timestamp("updated_at"),
});

export const projects = pgTable("projects", {
  id: serial("id").primaryKey(),
  name: text("name").notNull(),
  status: text("status").$type<ProjectStatus>().notNull(),
  description: text("description").notNull(),
  isPublic: boolean("is_public").default(false).notNull(),
  createdAt: timestamp("created_at", { mode: "date", precision: 3 })
    .defaultNow()
    .notNull(),
  updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate(
    () => new Date()
  ),
  ownerId: integer("owner_id")
    .notNull()
    .references(() => users.id, { onDelete: "restrict", onUpdate: "cascade" }),
});

export const members = pgTable("members", {
  id: serial("id").primaryKey(),
  role: text("role").$type<ProjectRole>().default("MEMBER").notNull(),
  createdAt: timestamp("created_at", { mode: "date", precision: 3 })
    .defaultNow()
    .notNull(),
  updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate(
    () => new Date()
  ),
  userId: integer("user_id")
    .notNull()
    .references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" }),
  projectId: integer("project_id")
    .notNull()
    .references(() => projects.id, {
      onDelete: "cascade",
      onUpdate: "cascade",
    }),
});

export const tasks = pgTable("tasks", {
  id: serial("id").primaryKey(),
  name: text("name").notNull(),
  label: text("label").$type<Label>().notNull(),
  status: text("status").$type<Status>().notNull(),
  priority: text("priority").$type<Priority>().notNull(),
  description: text("description").notNull(),
  dueDate: timestamp("due_date", { mode: "date", precision: 3 }).notNull(),
  createdAt: timestamp("created_at", { mode: "date", precision: 3 })
    .defaultNow()
    .notNull(),
  updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate(
    () => new Date()
  ),
  memberId: integer("member_id").references(() => members.id, {
    onDelete: "set null",
    onUpdate: "cascade",
  }),
  projectId: integer("project_id")
    .notNull()
    .references(() => projects.id, {
      onDelete: "cascade",
      onUpdate: "cascade",
    }),
});

export const invitationCodes = pgTable("invitation_codes", {
  id: serial("id").primaryKey(),
  code: text("code").notNull().unique(),
  projectId: integer("project_id")
    .notNull()
    .references(() => projects.id, { onDelete: "cascade" }),
  expiresAt: timestamp("expires_at", { mode: "date", precision: 3 }),
  createdAt: timestamp("created_at", { mode: "date", precision: 3 })
    .defaultNow()
    .notNull(),
  updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate(
    () => new Date()
  ),
});

export const membershipRequests = pgTable("membership_requests", {
  id: serial("id").primaryKey(),
  status: text("status")
    .$type<MembershipRequestStatus>()
    .default("PENDING")
    .notNull(),
  requesterId: integer("requester_id")
    .notNull()
    .references(() => users.id, {
      onDelete: "cascade",
      onUpdate: "cascade",
    }),
  projectId: integer("project_id")
    .notNull()
    .references(() => projects.id, {
      onDelete: "cascade",
      onUpdate: "cascade",
    }),
  createdAt: timestamp("created_at", { mode: "date", precision: 3 })
    .defaultNow()
    .notNull(),
  updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate(
    () => new Date()
  ),
});

signup call:

 await signUp.email({
      email: data.email,
      password: data.password,
      name: data.name,
      callbackURL: "/dashboard",
      fetchOptions: {
        onResponse: () => {
          setIsLoading(false);
        },
        onRequest: () => {
          setIsLoading(true);
        },
        onError: (ctx) => {
          console.log(ctx.error);
          toast.error(ctx.error.message);
        },
        onSuccess: async () => {
          router.push("/dashboard");
        },
      },
    });
Originally created by @knnedy on GitHub (Apr 9, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce To Reproduce 1. Create a default nextjs project with (my version is v15.2.4): ``` bash npx create-next-app@latest ``` 1. Install drizzle-orm packages also the postgres packages. 1. Install better-auth (my version is v1.2.5). 1. Create a login system(routes and auth_client) using better-auth. 1. Use signUp.email to signup and create the user. 1. ERROR on the terminal: [Better Auth]: Failed to create user TypeError: value.toISOString is not a function ### Current vs. Expected behavior Issue #1035 was closed without the soultion but I am not sure its the same issue. Error On the terminal: ```bash ERROR [Better Auth]: Failed to create user TypeError: value.toISOString is not a function at Array.map (<anonymous>) at Array.map (<anonymous>) at Array.map (<anonymous>) POST /api/auth/sign-up/email 422 in 1358ms ``` ### What version of Better Auth are you using? 1.2.5 ### Provide environment information ```bash - Framework: Next.js - Database adapter: Drizzle - Database: postgres - OS: Linux Ubuntu x86_64 ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import db from "@/database/db"; import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { nextCookies } from "better-auth/next-js"; export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", usePlural: true, }), emailAndPassword: { enabled: true, }, advanced: { generateId: false, }, plugins: [nextCookies()], }); ``` ### Additional context auth.ts: ```typescript import db from "@/database/db"; import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { nextCookies } from "better-auth/next-js"; export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", usePlural: true, }), emailAndPassword: { enabled: true, }, advanced: { generateId: false, }, plugins: [nextCookies()], }); ``` db schema: ```typescript import { timestamp, pgTable, text, integer, boolean, serial, } from "drizzle-orm/pg-core"; import { relations } from "drizzle-orm"; import { Label, MembershipRequestStatus, Priority, ProjectRole, ProjectStatus, Status, } from "@/lib/config"; export const users = pgTable("users", { id: serial("id").primaryKey(), name: text("name").notNull(), email: text("email").unique().notNull(), emailVerified: timestamp("email_verified", { mode: "date", precision: 3 }), image: text("image"), createdAt: timestamp("created_at", { mode: "date", precision: 3 }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate( () => new Date() ), }); export const accounts = pgTable("accounts", { id: serial("id").primaryKey(), accountId: text("account_id").notNull(), providerId: text("provider_id").notNull(), userId: integer("user_id") .notNull() .references(() => users.id), accessToken: text("access_token"), refreshToken: text("refresh_token"), idToken: text("id_token"), accessTokenExpiresAt: timestamp("access_token_expires_at"), refreshTokenExpiresAt: timestamp("refresh_token_expires_at"), scope: text("scope"), password: text("password"), createdAt: timestamp("created_at").notNull(), updatedAt: timestamp("updated_at").notNull(), }); export const sessions = pgTable("sessions", { id: serial("id").primaryKey(), expiresAt: timestamp("expires_at").notNull(), token: text("token").notNull().unique(), createdAt: timestamp("created_at").notNull(), updatedAt: timestamp("updated_at").notNull(), ipAddress: text("ip_address"), userAgent: text("user_agent"), userId: integer("user_id") .notNull() .references(() => users.id), }); export const verifications = pgTable("verifications", { id: serial("id").primaryKey(), identifier: text("identifier").notNull(), value: text("value").notNull(), expiresAt: timestamp("expires_at").notNull(), createdAt: timestamp("created_at"), updatedAt: timestamp("updated_at"), }); export const projects = pgTable("projects", { id: serial("id").primaryKey(), name: text("name").notNull(), status: text("status").$type<ProjectStatus>().notNull(), description: text("description").notNull(), isPublic: boolean("is_public").default(false).notNull(), createdAt: timestamp("created_at", { mode: "date", precision: 3 }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate( () => new Date() ), ownerId: integer("owner_id") .notNull() .references(() => users.id, { onDelete: "restrict", onUpdate: "cascade" }), }); export const members = pgTable("members", { id: serial("id").primaryKey(), role: text("role").$type<ProjectRole>().default("MEMBER").notNull(), createdAt: timestamp("created_at", { mode: "date", precision: 3 }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate( () => new Date() ), userId: integer("user_id") .notNull() .references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" }), projectId: integer("project_id") .notNull() .references(() => projects.id, { onDelete: "cascade", onUpdate: "cascade", }), }); export const tasks = pgTable("tasks", { id: serial("id").primaryKey(), name: text("name").notNull(), label: text("label").$type<Label>().notNull(), status: text("status").$type<Status>().notNull(), priority: text("priority").$type<Priority>().notNull(), description: text("description").notNull(), dueDate: timestamp("due_date", { mode: "date", precision: 3 }).notNull(), createdAt: timestamp("created_at", { mode: "date", precision: 3 }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate( () => new Date() ), memberId: integer("member_id").references(() => members.id, { onDelete: "set null", onUpdate: "cascade", }), projectId: integer("project_id") .notNull() .references(() => projects.id, { onDelete: "cascade", onUpdate: "cascade", }), }); export const invitationCodes = pgTable("invitation_codes", { id: serial("id").primaryKey(), code: text("code").notNull().unique(), projectId: integer("project_id") .notNull() .references(() => projects.id, { onDelete: "cascade" }), expiresAt: timestamp("expires_at", { mode: "date", precision: 3 }), createdAt: timestamp("created_at", { mode: "date", precision: 3 }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate( () => new Date() ), }); export const membershipRequests = pgTable("membership_requests", { id: serial("id").primaryKey(), status: text("status") .$type<MembershipRequestStatus>() .default("PENDING") .notNull(), requesterId: integer("requester_id") .notNull() .references(() => users.id, { onDelete: "cascade", onUpdate: "cascade", }), projectId: integer("project_id") .notNull() .references(() => projects.id, { onDelete: "cascade", onUpdate: "cascade", }), createdAt: timestamp("created_at", { mode: "date", precision: 3 }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { mode: "date", precision: 3 }).$onUpdate( () => new Date() ), }); ``` signup call: ```typescript await signUp.email({ email: data.email, password: data.password, name: data.name, callbackURL: "/dashboard", fetchOptions: { onResponse: () => { setIsLoading(false); }, onRequest: () => { setIsLoading(true); }, onError: (ctx) => { console.log(ctx.error); toast.error(ctx.error.message); }, onSuccess: async () => { router.push("/dashboard"); }, }, }); ```
Author
Owner

@Kinfe123 commented on GitHub (Apr 9, 2025):

this is probably a date issue , make sure you are passing a valid date object to any date fields here in db schema

@Kinfe123 commented on GitHub (Apr 9, 2025): this is probably a date issue , make sure you are passing a valid date object to any date fields here in db schema
Author
Owner

@knnedy commented on GitHub (Apr 9, 2025):

this is probably a date issue , make sure you are passing a valid date object to any date fields here in db schema

If better-auth handles the user creation during the signup flow using: signUp.email(userdata), isn't there are an issue with the package.

@knnedy commented on GitHub (Apr 9, 2025): > this is probably a date issue , make sure you are passing a valid date object to any date fields here in db schema If better-auth handles the user creation during the signup flow using: signUp.email(userdata), isn't there are an issue with the package.
Author
Owner

@Kinfe123 commented on GitHub (Apr 9, 2025):

better auth handles the auto creation but if you pass a custom one it overrides it ... how are you calling it ?

@Kinfe123 commented on GitHub (Apr 9, 2025): better auth handles the auto creation but if you pass a custom one it overrides it ... how are you calling it ?
Author
Owner

@Kinfe123 commented on GitHub (Apr 9, 2025):

May be try removing a precision on date to see it that is the case

@Kinfe123 commented on GitHub (Apr 9, 2025): May be try removing a precision on date to see it that is the case
Author
Owner

@Bekacru commented on GitHub (Apr 10, 2025):

Hey @KennyMwendwaX the issue is you have emailVerified field with timestamp data type. It should be boolean.

@Bekacru commented on GitHub (Apr 10, 2025): Hey @KennyMwendwaX the issue is you have `emailVerified` field with `timestamp` data type. It should be `boolean`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1017