[GH-ISSUE #5430] Non-public schema CLI migration #10242

Closed
opened 2026-04-13 06:14:10 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @martinriviere on GitHub (Oct 20, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/5430

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Description

When using a non-default PostgreSQL schema (e.g., auth) with Better Auth, the CLI migration command inspects tables from the public schema instead of the target schema. This causes it to generate incomplete migrations if a table with the same name (e.g., user) already exists in the public schema.

Steps to Reproduce

  1. Configure Better Auth to use a non-default schema (auth):
// better-auth.config.ts
import { betterAuth } from 'better-auth';
import { Pool } from 'pg';

const pool = new Pool({
  host: 'localhost',
  port: 5432,
  user: 'postgres',
  password: 'password',
  database: 'mydb',
  options: '-c search_path=auth', // Also tried with a connection string as in the doc, same issue
});

export const auth = betterAuth({
  database: pool,
  emailAndPassword: {
    enabled: true,
  },
});

export default auth;
  1. Have an existing table named user in the public schema:
CREATE TABLE public.user (
  id SERIAL PRIMARY KEY,
  email VARCHAR(255) NOT NULL,
  name VARCHAR(255)
);
  1. Run the CLI migration command:
npx better-auth migrate

Current vs. Expected behavior

Expected Behavior

The CLI should:

  1. Inspect the auth schema (not public)
  2. Detect that no user table exists in auth
  3. Generate a complete migration creating all necessary columns

Actual Behavior

The CLI:

  1. Inspects the public schema
  2. Detects an existing user table in public
  3. Generates a partial migration that only adds missing columns:
alter table "user" add column "emailVerified" boolean not null;
alter table "user" add column "image" text;
alter table "user" add column "createdAt" timestamptz default CURRENT_TIMESTAMP not null;
alter table "user" add column "updatedAt" timestamptz default CURRENT_TIMESTAMP not null;
  1. Attempts to execute these ALTER statements on the auth schema
  2. Fails because the user table doesn't exist in the auth schema

Error Message

error: relation "user" does not exist

What version of Better Auth are you using?

1.3.27

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:43 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T8132",
    "release": "24.5.0",
    "cpuCount": 10,
    "cpuModel": "Apple M4",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.12 GB"
  },
  "node": {
    "version": "v22.20.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "10.9.3"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "14.2.32"
    },
    {
      "name": "react",
      "version": "18.3.1"
    },
    {
      "name": "express",
      "version": "4.21.2"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "8.16.0"
    },
    {
      "name": "mongodb",
      "version": "5.9.2"
    }
  ],
  "betterAuth": {
    "version": "1.3.27",
    "config": {
      "database": {
        "_events": {},
        "_eventsCount": 1,
        "options": {
          "host": "localhost",
          "port": 5432,
          "user": "XXX",
          "database": "XXX",
          "options": "-c search_path=auth",
          "max": 10,
          "min": 0,
          "maxUses": null,
          "allowExitOnIdle": false,
          "maxLifetimeSeconds": 0,
          "idleTimeoutMillis": 10000
        },
        "_clients": [],
        "_idle": [],
        "_expired": {},
        "_pendingQueue": [],
        "ending": false,
        "ended": false
      }
    }
  }
}

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

Backend

Auth config (if applicable)


Additional context

No response

Originally created by @martinriviere on GitHub (Oct 20, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/5430 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce ### Description When using a non-default PostgreSQL schema (e.g., `auth`) with Better Auth, the CLI migration command inspects tables from the `public` schema instead of the target schema. This causes it to generate incomplete migrations if a table with the same name (e.g., `user`) already exists in the `public` schema. ### Steps to Reproduce 1. Configure Better Auth to use a non-default schema (`auth`): ```typescript // better-auth.config.ts import { betterAuth } from 'better-auth'; import { Pool } from 'pg'; const pool = new Pool({ host: 'localhost', port: 5432, user: 'postgres', password: 'password', database: 'mydb', options: '-c search_path=auth', // Also tried with a connection string as in the doc, same issue }); export const auth = betterAuth({ database: pool, emailAndPassword: { enabled: true, }, }); export default auth; ``` 2. Have an existing table named `user` in the `public` schema: ```sql CREATE TABLE public.user ( id SERIAL PRIMARY KEY, email VARCHAR(255) NOT NULL, name VARCHAR(255) ); ``` 3. Run the CLI migration command: ```bash npx better-auth migrate ``` ### Current vs. Expected behavior ### Expected Behavior The CLI should: 1. Inspect the `auth` schema (not `public`) 2. Detect that no `user` table exists in `auth` 3. Generate a complete migration creating all necessary columns ### Actual Behavior The CLI: 1. Inspects the `public` schema 2. Detects an existing `user` table in `public` 3. Generates a partial migration that only adds missing columns: ```sql alter table "user" add column "emailVerified" boolean not null; alter table "user" add column "image" text; alter table "user" add column "createdAt" timestamptz default CURRENT_TIMESTAMP not null; alter table "user" add column "updatedAt" timestamptz default CURRENT_TIMESTAMP not null; ``` 4. Attempts to execute these ALTER statements on the `auth` schema 5. Fails because the `user` table doesn't exist in the `auth` schema ### Error Message ``` error: relation "user" does not exist ``` ### What version of Better Auth are you using? 1.3.27 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:43 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T8132", "release": "24.5.0", "cpuCount": 10, "cpuModel": "Apple M4", "totalMemory": "16.00 GB", "freeMemory": "0.12 GB" }, "node": { "version": "v22.20.0", "env": "development" }, "packageManager": { "name": "npm", "version": "10.9.3" }, "frameworks": [ { "name": "next", "version": "14.2.32" }, { "name": "react", "version": "18.3.1" }, { "name": "express", "version": "4.21.2" } ], "databases": [ { "name": "pg", "version": "8.16.0" }, { "name": "mongodb", "version": "5.9.2" } ], "betterAuth": { "version": "1.3.27", "config": { "database": { "_events": {}, "_eventsCount": 1, "options": { "host": "localhost", "port": 5432, "user": "XXX", "database": "XXX", "options": "-c search_path=auth", "max": 10, "min": 0, "maxUses": null, "allowExitOnIdle": false, "maxLifetimeSeconds": 0, "idleTimeoutMillis": 10000 }, "_clients": [], "_idle": [], "_expired": {}, "_pendingQueue": [], "ending": false, "ended": false } } } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-13 06:14:10 -05:00
Author
Owner

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

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

This is a known limitation in Better Auth CLI migrations: the migration logic currently defaults to inspecting the public schema when generating migrations for PostgreSQL, even if you configure a different schema via search_path or connection options. As a result, if a table exists in public but not in your target schema (like auth), the CLI may generate incomplete migrations and fail with errors like relation "user" does not exist when applying changes to the non-public schema. There is no robust handling for non-public schemas in the migration CLI at this time, and manual intervention is often needed to resolve these conflicts or to ensure migrations are generated for the intended schema. This limitation is not documented in detail, but it is consistent with the current code and recent migration tests, which explicitly query and expect tables in the public schema example.

If you need to use a non-public schema, you may need to manually create the tables in your target schema before running migrations, or adjust the generated migration SQL to reference the correct schema. There is no configuration option in Better Auth CLI 1.3.27 to force schema selection for migrations.

To reply, just mention @dosu.


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

<!-- gh-comment-id:3422785210 --> @dosubot[bot] commented on GitHub (Oct 20, 2025): <!-- Greeting --> Hi @martinriviere! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known limitation in Better Auth CLI migrations: the migration logic currently defaults to inspecting the `public` schema when generating migrations for PostgreSQL, even if you configure a different schema via `search_path` or connection options. As a result, if a table exists in `public` but not in your target schema (like `auth`), the CLI may generate incomplete migrations and fail with errors like `relation "user" does not exist` when applying changes to the non-public schema. There is no robust handling for non-public schemas in the migration CLI at this time, and manual intervention is often needed to resolve these conflicts or to ensure migrations are generated for the intended schema. This limitation is not documented in detail, but it is consistent with the current code and recent migration tests, which explicitly query and expect tables in the `public` schema [example](https://github.com/better-auth/better-auth/pull/4867). If you need to use a non-public schema, you may need to manually create the tables in your target schema before running migrations, or adjust the generated migration SQL to reference the correct schema. There is no configuration option in Better Auth CLI 1.3.27 to force schema selection for migrations. <!-- 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/e51e6116-c423-4611-9e07-930d3c08d0b4?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/e51e6116-c423-4611-9e07-930d3c08d0b4?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/e51e6116-c423-4611-9e07-930d3c08d0b4?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/e51e6116-c423-4611-9e07-930d3c08d0b4?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/e51e6116-c423-4611-9e07-930d3c08d0b4?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/e51e6116-c423-4611-9e07-930d3c08d0b4?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/e51e6116-c423-4611-9e07-930d3c08d0b4?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/5430)
Author
Owner

@heyjainam commented on GitHub (Dec 27, 2025):

@martinriviere was your issue resolved? I am in latest version still seeing this issue where search path seems to be getting ignored

<!-- gh-comment-id:3693914354 --> @heyjainam commented on GitHub (Dec 27, 2025): @martinriviere was your issue resolved? I am in latest version still seeing this issue where search path seems to be getting ignored
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10242