Summary
PGLite brains at config.version=54 (pre-v60) can't advance to v66 because applyForwardReferenceBootstrap in src/core/pglite-engine.ts doesn't add oauth_clients.source_id + oauth_clients.federated_read before PGLITE_SCHEMA_SQL replay. The replay's CREATE INDEX ON oauth_clients(source_id) then fails with a misleading one-line error before runMigrations() runs.
Repro
- Brain at
config.version=54 (pre-v60 schema)
- Upgrade binary to v0.34.x
- Run
gbrain init --migrate-only
$ gbrain init --migrate-only
column "source_id" does not exist
EXIT=1
No stack trace. Migration runner never reaches v55.
Expected
12 migrations (v55-v66) apply; config.version advances to 66.
Actual
initSchema()'s SCHEMA_SQL replay fails on CREATE INDEX idx_oauth_clients_source_id, the cli.ts try/catch swallows it, runMigrations() is never called. Brain stays at v54 indefinitely.
Compounding: gbrain doctor reports Fix: gbrain apply-migrations --yes for the schema_version check — but that's the orchestrator runner, not the schema runner. The correct verb is gbrain init --migrate-only (which itself fails per above).
Root cause
pglite-engine.ts:247-250 explicitly states:
when a future migration adds a column-with-index or new-table-with-FK referenced by PGLITE_SCHEMA_SQL, extend this method AND test/schema-bootstrap-coverage.test.ts's REQUIRED_BOOTSTRAP_COVERAGE.
v60's oauth_clients_source_id_fk migration added the columns + FK, and PGLITE_SCHEMA_SQL declares indexes on both — but the bootstrap function and the coverage test were not extended.
Suggested fix
// In applyForwardReferenceBootstrap:
await this.db.exec(`
ALTER TABLE oauth_clients
ADD COLUMN IF NOT EXISTS source_id TEXT REFERENCES sources(id) ON DELETE RESTRICT;
ALTER TABLE oauth_clients
ADD COLUMN IF NOT EXISTS federated_read TEXT[] NOT NULL DEFAULT '{}';
`);
Plus add both columns to REQUIRED_BOOTSTRAP_COVERAGE in test/schema-bootstrap-coverage.test.ts.
Separately: update doctor's schema_version check fix hint in src/commands/doctor.ts from gbrain apply-migrations --yes to gbrain init --migrate-only.
Workaround
Run the two ALTER TABLE statements above directly against PGLite (via a Bun script opening the DB with extensions: { vector, pg_trgm }), then re-run gbrain init --migrate-only. Migrations v55-v66 apply cleanly. Safe on empty oauth_clients; backfills in v60-v62 handle non-empty tables.
Environment
- gbrain v0.34.4.0 (HEAD
24881f6)
- PGLite 0.4.3, pgvector 0.8.1
- macOS 26.4.1, Apple Silicon
- Brain: 124 pages, empty
oauth_clients
Summary
PGLite brains at
config.version=54(pre-v60) can't advance to v66 becauseapplyForwardReferenceBootstrapinsrc/core/pglite-engine.tsdoesn't addoauth_clients.source_id+oauth_clients.federated_readbefore PGLITE_SCHEMA_SQL replay. The replay'sCREATE INDEX ON oauth_clients(source_id)then fails with a misleading one-line error beforerunMigrations()runs.Repro
config.version=54(pre-v60 schema)gbrain init --migrate-only$ gbrain init --migrate-only
column "source_id" does not exist
EXIT=1
No stack trace. Migration runner never reaches v55.
Expected
12 migrations (v55-v66) apply;
config.versionadvances to 66.Actual
initSchema()'s SCHEMA_SQL replay fails onCREATE INDEX idx_oauth_clients_source_id, the cli.ts try/catch swallows it,runMigrations()is never called. Brain stays at v54 indefinitely.Compounding:
gbrain doctorreportsFix: gbrain apply-migrations --yesfor the schema_version check — but that's the orchestrator runner, not the schema runner. The correct verb isgbrain init --migrate-only(which itself fails per above).Root cause
pglite-engine.ts:247-250explicitly states:v60's
oauth_clients_source_id_fkmigration added the columns + FK, and PGLITE_SCHEMA_SQL declares indexes on both — but the bootstrap function and the coverage test were not extended.Suggested fix
Plus add both columns to
REQUIRED_BOOTSTRAP_COVERAGEintest/schema-bootstrap-coverage.test.ts.Separately: update doctor's
schema_versioncheck fix hint insrc/commands/doctor.tsfromgbrain apply-migrations --yestogbrain init --migrate-only.Workaround
Run the two
ALTER TABLEstatements above directly against PGLite (via a Bun script opening the DB withextensions: { vector, pg_trgm }), then re-rungbrain init --migrate-only. Migrations v55-v66 apply cleanly. Safe on emptyoauth_clients; backfills in v60-v62 handle non-empty tables.Environment
24881f6)oauth_clients