fix(migrations): propagate GBRAIN_DATABASE_URL + GBRAIN_DISABLE_DIRECT_POOL to migration subprocesses (IPv6 band-aid)#1005
Open
diazMelgarejo wants to merge 1 commit into
Conversation
…T_POOL to subprocess env
Migration orchestrators spawn child processes via execSync with
`env: process.env`. On machines where the database URL is a Supabase
Session Pooler (port 6543), connection-manager.ts auto-derives a
direct URL (`db.<ref>.supabase.co:5432`) for DDL operations. That
hostname is IPv6-only on many networks, causing ECONNREFUSED in every
migration subprocess.
Each orchestrator now calls _childEnv() which:
1. Reads ~/.gbrain/config.json to guarantee GBRAIN_DATABASE_URL
is set to the configured pooler URL in child env
2. Sets GBRAIN_DISABLE_DIRECT_POOL=1 to suppress direct-URL
derivation in the child process connection-manager
Affected: v0.11.0, v0.12.0, v0.12.2, v0.13.0, v0.16.0, v0.18.0,
v0.18.1, v0.21.0, v0.29.1
Repro: Supabase Session Pooler (port 6543), IPv4-only or
IPv4-preferred network, run `gbrain apply-migrations --yes`.
All orchestrator-spawned subprocesses fail with ECONNREFUSED
against db.<ref>.supabase.co:5432.
See: garrytan/gstack#1301
Note: This is a band-aid. The principled fix is to not derive a
direct URL at all when the primary URL is already a Session Pooler
(port 6543), since Session Pooler supports DDL natively. See
companion PR on connection-manager.ts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced May 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
gbrain apply-migrations --yesfails on networks where Supabase's direct connection (db.<ref>.supabase.co:5432) is IPv6-only — which is the default for most Supabase projects.Root cause chain
connection-manager.ts:deriveDirectUrl()detects a pooler URL and auto-derivesdb.<ref>.supabase.co:5432for DDL operationsapply-migrations.tsruns orchestrators; orchestrators spawn child subprocesses viaexecSync('gbrain init --migrate-only', { env: process.env })process.env— but this may not containGBRAIN_DATABASE_URL(it was loaded from~/.gbrain/config.jsonat parent startup, not re-exported to env)connection-manager.tsderives the IPv6-only direct URL, andddl()calls fail withECONNREFUSEDRepro
gbrain apply-migrations --yes→ ECONNREFUSED on all orchestrator-spawned subprocessesRelated: garrytan/gstack#1301
See also: garrytan/gstack#1249 (similar IPv6-avoidance pattern in browse module)
This fix (band-aid)
Add
_childEnv()to each migration orchestrator that:~/.gbrain/config.json→ guaranteesGBRAIN_DATABASE_URLis the pooler URL in child envGBRAIN_DISABLE_DIRECT_POOL=1→ suppressesderiveDirectUrl()in the child'sconnection-managerFiles changed: v0.11.0, v0.12.0, v0.12.2, v0.13.0, v0.16.0, v0.18.0, v0.18.1, v0.21.0, v0.29.1
Why this is a band-aid
_childEnv()is duplicated across 9 filesGBRAIN_DISABLE_DIRECT_POOL=1is a blunt instrument (affects ALL operations in the child, not just DDL)The principled fix
deriveDirectUrl()should not derive a direct URL when the primary URL is already a Session Pooler (port 6543). Session Pooler maintains session state and supports DDL natively — the whole reason for the dual-pool architecture was to work around Transaction Pooler's statelessness and 2-minute statement timeout. Session Pooler has neither of those constraints.A companion PR with that 4-line fix to
connection-manager.tsmakes this 126-line band-aid unnecessary.Happy to PR the band-aid fix if useful
Verified working on:
aws-1-ap-northeast-1.pooler.supabase.com)