Skip to content

Migration files edited in place break sqlx checksums for any long-lived database on image upgrade #2472

Description

@vsima

Environment

  • Database migrated by ghcr.io/block/buzz:sha-2d26db6
    (2d26db6…, 2026-06-16, includes auto-migrate Add automatic database migrations #988)
  • Upgraded to ghcr.io/block/buzz:sha-acfbb1b
    (acfbb1bb…, 2026-07-22 main)
  • External Cloud SQL Postgres 16, BUZZ_AUTO_MIGRATE=true

What happens

The newer relay refuses to start against the June-migrated database:

ERROR Failed to run database migrations: migration error: migration 1 was previously applied but has been modified

sqlx records a checksum per applied migration; at least migration 1 was
edited in place between 2026-06-16 and 2026-07-22, so every database migrated
in that window fails checksum validation on upgrade. There is no forward path
for the deployment at that point — the options are hand-editing
_sqlx_migrations rows (leaves schema drift if the edit changed shape) or
dropping the schema (we did the latter; it was a pilot with test data — a
production tenant DB could not do this).

Why this matters for deployers

Buzz positions the relay as self-hostable with BUZZ_AUTO_MIGRATE as the
upgrade path (#988). In-place edits to already-shipped migrations silently
convert every existing database into an upgrade dead-end. Anyone running a
relay across that window — self-hosters included — hits this on their next
image pull.

Proposal

  1. Append-only discipline for shipped migrations — once a migration has
    appeared in any published image (ghcr tags count), it is frozen; changes
    land as new migrations.
  2. If a squash/reset is ever genuinely needed, ship it as an explicit,
    versioned baseline migration with a documented cut-over (e.g. "relay
    ≥ X requires DB baseline Y; run the provided re-baseline tool"), not as a
    silent edit.
  3. A CI check on the repo enforcing (1) is cheap: compare checksums of
    migrations/* against the previous release tag and fail on modification.

Happy to contribute the CI check.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions