{"record":{"id":"bff5da19e8aa0c4c","repo":"gastownhall/beads","slug":"unstaging-pre-migration-tables-w","errorCode":null,"errorMessage":"unstaging pre-migration tables: %w","messagePattern":"unstaging pre-migration tables: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/schema.go","lineNumber":603,"sourceCode":"\t\tif seedChanged {\n\t\t\tif err := commitSeededDoltIgnore(ctx, db); err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t\treturn 0, nil\n\t}\n\n\tdirtyBeforeAll, err := dirtyTables(ctx, db, false)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"reading pre-migration status: %w\", err)\n\t}\n\t// dolt_ignore is pass-owned state: seedDoltIgnorePatterns above may have\n\t// just dirtied it on an under-seeded database. Exempting it from the\n\t// pre-existing-dirty guards (like the aux-rekey tables below) keeps the\n\t// pending-migration and changed-signature gates off it.\n\tdelete(dirtyBeforeAll, \"dolt_ignore\")\n\tif err := unstagePreExistingTables(ctx, db, dirtyBeforeAll); err != nil {\n\t\treturn 0, fmt.Errorf(\"unstaging pre-migration tables: %w\", err)\n\t}\n\t// The seed must not ride the migration pass: every step of the pass\n\t// commits atomically, and a pass killed between steps must leave a CLEAN\n\t// working set (the #4566 self-heal contract) — but the seeded dolt_ignore\n\t// rows would stay dirty until the pass's final commit, so an interrupted\n\t// retry sees a dirty working set and refuses to converge. Commit the seed\n\t// scoped and labeled now, after pre-existing staged tables were unstaged\n\t// (so nothing else rides into the commit) and before the first step runs.\n\tif seedChanged {\n\t\tif err := commitSeededDoltIgnore(ctx, db); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\tdirtyBefore, err := committableDirtyTables(ctx, db)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"reading pre-migration status: %w\", err)\n\t}\n\tdelete(dirtyBefore, \"dolt_ignore\")","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/schema.go#L585-L621","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: user-staged tables block unstaging\n$ dolt status // staged: my_table\n$ bd migrate // fails unstaging pre-migration tables\n// after: commit or reset the staged change first\n$ dolt commit -m \"user change\"\n$ bd migrate","handlingStrategy":"validation","validationCode":"// ensure no foreign staged tables before migrating\nrows, err := db.QueryContext(ctx, \"CALL DOLT_STATUS()\")\nfor rows.Next() {\n\tvar table, state string\n\t_ = rows.Scan(&table, &state)\n\tif table != \"dolt_ignore\" {\n\t\treturn fmt.Errorf(\"table %s is staged; commit or reset first\", table)\n\t}\n}","typeGuard":null,"tryCatchPattern":"_, err := schema.MigrateUp(ctx, db)\nif err != nil && strings.Contains(err.Error(), \"unstaging pre-migration tables\") {\n\t// manually commit/reset staged user tables, then retry\n\treturn fmt.Errorf(\"resolve staged tables manually: %w\", err)\n}","preventionTips":["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"],"tags":["dolt","migration","staging","working-set"],"backgroundTag":"dolt-unstage-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}