gastownhall/beads · error
unstaging pre-migration tables: %w
Error message
unstaging pre-migration tables: %w
What it means
This error wraps a failure of `unstagePreExistingTables` — before migrating, MigrateUp unstages any pre-existing dirty tables (after exempting pass-owned dolt_ignore) so migration steps commit atomically. Failing here aborts before the first migration step, protecting the clean-working-set contract.
Source
Thrown at internal/storage/schema/schema.go:603
if seedChanged {
if err := commitSeededDoltIgnore(ctx, db); err != nil {
return 0, err
}
}
return 0, nil
}
dirtyBeforeAll, err := dirtyTables(ctx, db, false)
if err != nil {
return 0, fmt.Errorf("reading pre-migration status: %w", err)
}
// dolt_ignore is pass-owned state: seedDoltIgnorePatterns above may have
// just dirtied it on an under-seeded database. Exempting it from the
// pre-existing-dirty guards (like the aux-rekey tables below) keeps the
// pending-migration and changed-signature gates off it.
delete(dirtyBeforeAll, "dolt_ignore")
if err := unstagePreExistingTables(ctx, db, dirtyBeforeAll); err != nil {
return 0, fmt.Errorf("unstaging pre-migration tables: %w", err)
}
// The seed must not ride the migration pass: every step of the pass
// commits atomically, and a pass killed between steps must leave a CLEAN
// working set (the #4566 self-heal contract) — but the seeded dolt_ignore
// rows would stay dirty until the pass's final commit, so an interrupted
// retry sees a dirty working set and refuses to converge. Commit the seed
// scoped and labeled now, after pre-existing staged tables were unstaged
// (so nothing else rides into the commit) and before the first step runs.
if seedChanged {
if err := commitSeededDoltIgnore(ctx, db); err != nil {
return 0, err
}
}
dirtyBefore, err := committableDirtyTables(ctx, db)
if err != nil {
return 0, fmt.Errorf("reading pre-migration status: %w", err)
}
delete(dirtyBefore, "dolt_ignore")View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause; run `dolt status` to see what is staged
- Manually unstage or commit the pre-existing changes (`dolt reset` / `dolt commit`)
- Ensure dolt_ignore is not the blocker — it is exempted automatically; other staged tables are not
- Retry MigrateUp once the working set is clean
Example fix
// before: user-staged tables block unstaging $ dolt status // staged: my_table $ bd migrate // fails unstaging pre-migration tables // after: commit or reset the staged change first $ dolt commit -m "user change" $ bd migrate
Defensive patterns
Strategy: validation
Validate before calling
// ensure no foreign staged tables before migrating
rows, err := db.QueryContext(ctx, "CALL DOLT_STATUS()")
for rows.Next() {
var table, state string
_ = rows.Scan(&table, &state)
if table != "dolt_ignore" {
return fmt.Errorf("table %s is staged; commit or reset first", table)
}
} Try / catch
_, err := schema.MigrateUp(ctx, db)
if err != nil && strings.Contains(err.Error(), "unstaging pre-migration tables") {
// manually commit/reset staged user tables, then retry
return fmt.Errorf("resolve staged tables manually: %w", err)
} Prevention
- Don't leave user changes staged in the workspace when running bd migrate
- Commit or reset staged tables before migrations — only dolt_ignore is auto-exempted
- Use the locked migration path to avoid interleaved staging from concurrent processes
When it happens
Trigger: MigrateUp calling unstagePreExistingTables for dirtyBeforeAll tables when a DOLT_RESET/unstage call fails — conflicts in the working set, a Dolt server rejecting procedure calls, or a read-only store.
Common situations: Pre-existing staged changes from a crashed prior process that cannot be reset; Dolt server in a conflicted state; running migrations against a database whose working set contains user changes staged outside bd.
Related errors
- staging seeded dolt_ignore patterns: %w
- reading pre-migration status: %w
- staging migrations: %w
- dolt add %s: %w
- clone from %s succeeded, but the database needs %d schema %s
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/bff5da19e8aa0c4c.
Report an issue: GitHub.