[PR #7137] [CLOSED] fix: postgres escaped search_path #7095

Closed
opened 2026-03-13 13:23:54 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7137
Author: @Diabl0570
Created: 1/5/2026
Status: Closed

Base: canaryHead: canary


📄 Description

Updating the PR description to mention that Supabase escapes the $user search_path and include the link:

[1 tool called]

Fix PostgreSQL schema detection for escaped $user in search_path

Problem

When running migrations on PostgreSQL, users could see the following warning:

Schema '\$user' does not exist. Tables will be inspected from available schemas.

This occurred because the getPostgresSchema function wasn't properly filtering out the escaped variant of the PostgreSQL $user variable from the search_path.

Cause

PostgreSQL's search_path can return the $user variable in different formats:

  • $user (unescaped) - standard PostgreSQL default
  • \$user (escaped) - used by some providers like Supabase

Some managed PostgreSQL providers (notably Supabase) escape the $user variable in the search_path, returning "\$user", public, extensions instead of the standard "$user", public. This is a known difference from standard PostgreSQL behavior.

The original filter only checked for strings starting with $:

.filter((s) => !s.startsWith("$"))

This missed \$user since it starts with \, not $, causing the function to incorrectly treat it as a valid schema name.

Solution

Updated the filter to use a regex that handles both escaped and non-escaped variants:

.filter((s) => !/^\\?\$/.test(s))

This regex matches any string starting with an optional backslash followed by a dollar sign, correctly filtering out both $user and \$user. The function now properly falls through to return the next valid schema (like public) or defaults to "public" if none remain.

Testing

This fix ensures compatibility with both standard PostgreSQL installations and managed providers like Supabase that escape the $user variable.


Summary by cubic

Fixed PostgreSQL schema detection when providers escape $user in search_path, preventing false warnings and correctly choosing the next valid schema (e.g., public).

  • Bug Fixes
    • Filter both user and \$user with a regex that matches an optional backslash before .
    • Removes the "Schema '$user' does not exist" warning in migrations; compatible with Supabase’s escaped search_path (https://github.com/supabase/supabase/issues/20842).

Written for commit ac0cb53ec0. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/7137 **Author:** [@Diabl0570](https://github.com/Diabl0570) **Created:** 1/5/2026 **Status:** ❌ Closed **Base:** `canary` ← **Head:** `canary` --- ### 📄 Description Updating the PR description to mention that Supabase escapes the `$user` search_path and include the link: [1 tool called] ## Fix PostgreSQL schema detection for escaped `$user` in search_path ### Problem When running migrations on PostgreSQL, users could see the following warning: ``` Schema '\$user' does not exist. Tables will be inspected from available schemas. ``` This occurred because the `getPostgresSchema` function wasn't properly filtering out the escaped variant of the PostgreSQL `$user` variable from the `search_path`. ### Cause PostgreSQL's `search_path` can return the `$user` variable in different formats: - `$user` (unescaped) - standard PostgreSQL default - `\$user` (escaped) - used by some providers like Supabase Some managed PostgreSQL providers (notably [Supabase](https://github.com/supabase/supabase/issues/20842)) escape the `$user` variable in the search_path, returning `"\$user", public, extensions` instead of the standard `"$user", public`. This is a known difference from standard PostgreSQL behavior. The original filter only checked for strings starting with `$`: ```javascript .filter((s) => !s.startsWith("$")) ``` This missed `\$user` since it starts with `\`, not `$`, causing the function to incorrectly treat it as a valid schema name. ### Solution Updated the filter to use a regex that handles both escaped and non-escaped variants: ```javascript .filter((s) => !/^\\?\$/.test(s)) ``` This regex matches any string starting with an optional backslash followed by a dollar sign, correctly filtering out both `$user` and `\$user`. The function now properly falls through to return the next valid schema (like `public`) or defaults to `"public"` if none remain. ### Related Issues - [Supabase Issue #20842](https://github.com/supabase/supabase/issues/20842) - Documents Supabase's use of escaped `\$user` in search_path ### Testing This fix ensures compatibility with both standard PostgreSQL installations and managed providers like Supabase that escape the `$user` variable. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Fixed PostgreSQL schema detection when providers escape $user in search_path, preventing false warnings and correctly choosing the next valid schema (e.g., public). - **Bug Fixes** - Filter both $user and \$user with a regex that matches an optional backslash before $. - Removes the "Schema '\$user' does not exist" warning in migrations; compatible with Supabase’s escaped search_path (https://github.com/supabase/supabase/issues/20842). <sup>Written for commit ac0cb53ec02c9802ceb674f64821662656287f35. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-03-13 13:23:54 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#7095