Skip to content

fix: auto-detect PgBouncer transaction mode and disable prepared statements#284

Closed
garrytan wants to merge 1 commit into
masterfrom
wintermute/pgbouncer-prepare-fix
Closed

fix: auto-detect PgBouncer transaction mode and disable prepared statements#284
garrytan wants to merge 1 commit into
masterfrom
wintermute/pgbouncer-prepare-fix

Conversation

@garrytan

Copy link
Copy Markdown
Owner

Auto-detect Supabase PgBouncer (port 6543) and disable prepared statements. See commit message for details. 11 tests. Doctor check included. Do NOT merge — Garry will review and fix.

…ements (#260)

When the connection URL targets port 6543 (Supabase PgBouncer convention),
gbrain now automatically sets prepare=false on the postgres.js connection.
This prevents 'prepared statement does not exist' errors that silently drop
pages during sync when multiple gbrain processes (autopilot, jobs worker,
sync) compete for pooled connections.

Precedence chain:
  1. GBRAIN_PREPARE env var (explicit override)
  2. ?prepare= query param in URL
  3. Auto-detect: port 6543 → disable
  4. Default: postgres.js default (enabled)

Also adds:
- Doctor check: warns if port 6543 detected with prepare still enabled
- resolvePrepare() exported for testability
- 11 unit tests covering all precedence paths

Root cause: PgBouncer in transaction mode multiplexes clients across backend
connections. Prepared statements are connection-scoped in Postgres, so a
statement prepared on connection A fails when routed to connection B.

Discovered during batch enrichment of 4,500+ brain pages where sync silently
skipped pages with 'prepared statement ql7ganp7eyh25 does not exist'.

Co-Authored-By: Wintermute <wintermute@openclaw.ai>
garrytan added a commit that referenced this pull request Apr 22, 2026
Without this, \`gbrain jobs work\` against a Supabase pooler URL hits
"prepared statement does not exist" under load even after the module
singleton was fixed in db.ts. Community PR #270 (@notjbg) caught this
second path that #284 had missed. Reuses the shared helper, no regex
duplication.

Co-Authored-By: Jonah Berg <jonah.berg.g@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
garrytan added a commit that referenced this pull request Apr 22, 2026
- test/resolve-prepare.test.ts: 11 cases covering env override, URL
  query param, port auto-detect, malformed URLs, postgres:// scheme,
  URL-encoded credentials. Uses bun:test — #284's original vitest file
  would never have run in this project.
- test/postgres-engine.test.ts: new source-level grep case asserting
  the worker-pool connect() branch calls db.resolvePrepare(url) and
  includes a typeof prepare === 'boolean' check. Mirrors the existing
  SET LOCAL regression guard. If anyone rips out the wiring, the build
  fails before shipping starts dropping rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@garrytan garrytan closed this in fcf40a1 Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant