Skip to content

fix(migrate): 0002 ALTER ADD COLUMN REFERENCES + DEFAULT — P0 deploy outage#87

Merged
viktor-shcherb merged 1 commit intomainfrom
fix/m1-migration-alter-add-references-default
May 7, 2026
Merged

fix(migrate): 0002 ALTER ADD COLUMN REFERENCES + DEFAULT — P0 deploy outage#87
viktor-shcherb merged 1 commit intomainfrom
fix/m1-migration-alter-add-references-default

Conversation

@viktor-shcherb
Copy link
Copy Markdown
Member

Summary

P0 hotfix: the post-merge deploy of M1 (#86) failed at migration 0002
and Murmur is currently down (502 on https://murmur.colophon-group.org;
container in a crash loop). This PR restores it.

Root cause. SQLite forbids ALTER TABLE ADD COLUMN ... NOT NULL DEFAULT '<value>' REFERENCES ... when foreign_keys=ON AND the
target table already has rows. Locally the test suite ran against a
fresh :memory: pipelines (no rows), so the ALTER succeeded. In
production the demo publisher's existing pipeline row triggered
Cannot add a REFERENCES column with non-NULL default value. The
migration runner's BEGIN IMMEDIATE / COMMIT wrapper rolled the
failed migration back atomically, so the prod DB is unchanged and this
fix can re-apply cleanly.

Fix. Split the ALTER into two statements:

ALTER TABLE pipelines ADD COLUMN publisher_id TEXT REFERENCES publishers(id);
UPDATE pipelines SET publisher_id = 'pub_demo_seed' WHERE publisher_id IS NULL;

The schema-level NOT NULL is traded for an application-level
invariant — mountPipelineRoutes always supplies publisher_id from
c.var.publisher_id. Test fixtures that INSERT directly into
pipelines now include publisher_id = 'pub_demo_seed' explicitly
(the previous DEFAULT was supplying it for the few tests that
bypassed the API).

Documented in docs/auth.md / src/db/schema.md. A future migration
can rebuild the table to recover schema-level NOT NULL once the
migration runner supports PRAGMA foreign_keys=OFF (the toggle can't
go inside a single transaction).

Test plan

  • Reproduced the failing ALTER locally against a SQLite DB with an
    existing pipelines row (mirrors prod state) — fix applies cleanly.
  • pnpm test:unit — 391 tests pass (test fixtures updated for the
    explicit publisher_id value).
  • pnpm lint, pnpm typecheck, pnpm grep:all — green.
  • Post-merge: re-run deploy, verify /health=200,
    ssh murmur 'docker logs --tail 30 murmur' shows
    bootstrap.demo_publisher_seeded.
  • Smoke: jobseek's existing start-run.ts flow still authenticates.

🤖 Generated with Claude Code

…LL DEFAULT

The post-merge deploy of M1 (#86) failed at migration 0002 with
`Cannot add a REFERENCES column with non-NULL default value` and the
container went into a crash loop, taking https://murmur.colophon-group.org
down (502).

Root cause: SQLite forbids `ALTER TABLE ADD COLUMN ... NOT NULL DEFAULT
'<value>' REFERENCES ...` when foreign_keys=ON AND the table has
existing rows. The local test suite hit it against a fresh `:memory:`
DB (no rows), so the ALTER passed and the gate stayed green; the
production `pipelines` table held the demo's existing row, so the
ALTER tripped the rule.

Fix: split the ALTER into two statements:

  ALTER TABLE pipelines ADD COLUMN publisher_id TEXT REFERENCES publishers(id);
  UPDATE pipelines SET publisher_id = 'pub_demo_seed' WHERE publisher_id IS NULL;

The schema-level NOT NULL guarantee is traded for an application-level
invariant — `mountPipelineRoutes` always supplies `publisher_id` from
`c.var.publisher_id`. Test fixtures that INSERT directly into
`pipelines` now include `publisher_id = 'pub_demo_seed'` explicitly
(the previous DEFAULT was supplying it).

A future migration can rebuild the table to recover schema-level
NOT NULL once the migration runner supports a `PRAGMA foreign_keys=OFF`
toggle (the toggle can't go inside a single BEGIN IMMEDIATE / COMMIT).

Smoke-tested locally: identical `ALTER ... REFERENCES ... ; UPDATE`
sequence applied successfully against a SQLite DB with an existing
`pipelines` row (mirroring the failing prod state). All M1 tests + the
grandfather-token + subcommand_bearer seed paths still pass (391 tests
green).

Closes the M1 deploy outage; the migration runner's BEGIN IMMEDIATE /
COMMIT wrapping rolls the failed migration back atomically, so the
production DB schema is unchanged and this fix can re-apply cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@viktor-shcherb viktor-shcherb merged commit 66a06e8 into main May 7, 2026
2 checks passed
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