Skip to content

v0.14.x initSchema fails with "column link_source does not exist" when upgrading a PGLite brain from schema v10 (v0.12.x) #266

@gopalpatel

Description

@gopalpatel

Hi Garry — running into a chicken-and-egg in initSchema when upgrading an existing PGLite brain from v0.12.3 (schema version 10) to master (v0.14.2).

Reproducer

Starting from a brain at schema version 10 (the v0.12.3 baseline — drop_timeline_search_trigger):

cd ~/gbrain-tmp
git fetch origin && git reset --hard origin/master  # lands on v0.14.2
bun install && bun link
gbrain apply-migrations --yes

Output:

=== Applying migration v0.12.2: JSONB double-encode repair ===
column "link_source" does not exist
Migration v0.12.2 reported status=failed.

Same error from gbrain init --migrate-only directly.

Root cause

src/core/pglite-schema.ts:82-83 has:

CREATE INDEX IF NOT EXISTS idx_links_source ON links(link_source);
CREATE INDEX IF NOT EXISTS idx_links_origin ON links(origin_page_id);

These reference columns that are added by migration v11 (links_provenance_columns) in src/core/migrate.ts:288. But PGLiteEngine.initSchema() runs PGLITE_SCHEMA_SQL before it calls runMigrations:

// src/core/pglite-engine.ts:63-70
async initSchema(): Promise<void> {
  await this.db.exec(PGLITE_SCHEMA_SQL);   // <-- fails here on existing v10 brain
  const { applied } = await runMigrations(this);
  ...
}

CREATE INDEX IF NOT EXISTS guards by index name, not column existence — so for a brain already carrying idx_links_from / idx_links_to / etc. from its v10 state, the new idx_links_source doesn't exist yet and must be created, but the column it references also doesn't exist yet. SQL fails, runMigrations never runs, v11 never applies, user is stuck.

A fresh brain (gbrain init --pglite) isn't affected — the CREATE TABLE defines link_source in the initial schema, then the indexes create cleanly. Only users who went through the v0.11/v0.12 wave hit this.

What I tried

  1. gbrain apply-migrations --yes — fails at Phase A
  2. gbrain apply-migrations --force-retry 0.12.2 → re-run — same failure
  3. gbrain init --migrate-only directly — same failure
  4. I considered a direct invocation of runMigrations(engine) to apply v11 first and then retry initSchema, but that bypasses the sanctioned CLI path and felt wrong to apply to a production brain.

Reverted cleanly to v0.12.3 and held.

Possible fixes

  • Swap order in initSchema: call runMigrations first, then exec PGLITE_SCHEMA_SQL. Upstream migrations add columns → subsequent CREATE INDEX succeeds. A fresh brain would first create the tables (no rows, nothing to migrate), then re-exec schema SQL as a no-op.
  • Or guard the index creation: wrap the two problematic CREATE INDEX statements with a conditional that checks information_schema.columns for the target column, similar to the PG15+ guard in migrate.ts v11.
  • Or add ALTER TABLE IF NOT EXISTS ADD COLUMN for the three new columns in the schema SQL itself, ahead of the indexes — makes the SQL safely reentrant across schema generations.

Environment

  • gbrain source at b5fa3d0 (v0.14.2)
  • PGLite 0.4.4
  • bun 1.3.12
  • Linux ARM64 (NVIDIA DGX Spark)
  • Brain: ~2,066 pages, schema version 10, PGLite (single-user)

Happy to test any fix branch. Thanks for shipping the v0.13 wave — the graph enrichment from frontmatter indexing is exciting, just need a clear path to get there from an existing brain.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions