{"record":{"id":"dbd3c54d3977a15a","repo":"gastownhall/beads","slug":"backfill-custom-tables-w","errorCode":null,"errorMessage":"backfill custom tables: %w","messagePattern":"backfill custom tables: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/schema.go","lineNumber":662,"sourceCode":"\t\treturn 0, fmt.Errorf(\"reading pre-migration dirty table diffs: %w\", err)\n\t}\n\t// Captured before the main migrations run: the aux re-key uses it to\n\t// distinguish the lineage's first rekey-aware migration (run the pass)\n\t// from a fresh clone of an already-converged lineage (record the marker\n\t// only, bd-578h9.4).\n\tmainVersionBefore, err := mainSource.currentVersion(ctx, db)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"reading pre-migration schema version: %w\", err)\n\t}\n\n\tapplied, mainColumnAdded, err := mainSource.migrate(ctx, db, 0)\n\tif err != nil {\n\t\treturn applied, err\n\t}\n\n\tbackfilled, err := ensureBackfilledCustomStatusesCustomTypes(ctx, db)\n\tif err != nil {\n\t\treturn applied, fmt.Errorf(\"backfill custom tables: %w\", err)\n\t}\n\n\t// #4259: rewrite any per-clone-random dependency ids (minted by 0043's\n\t// DEFAULT (UUID()) before this fix) to the deterministic key, so independently\n\t// migrated clones converge to byte-identical, merge-safe dependencies. Runs\n\t// here, after the schema migrations (0050 has asserted the canonical schema),\n\t// and only on a pass where migration work was needed.\n\trekeyed, err := rekeyDependencyIDs(ctx, db)\n\tif err != nil {\n\t\treturn applied, fmt.Errorf(\"rekey dependency ids: %w\", err)\n\t}\n\tbackfilled = backfilled || rekeyed\n\n\t// bd-6dnrw.2: converge the events/comments/snapshots primary keys that\n\t// migration 0037 randomized per-clone, the same hazard class on the aux\n\t// tables. Gated on the clone-local ignored marker (recorded later in this\n\t// pass by ignoredSource.migrate) so it runs exactly once per clone instead\n\t// of churning synced rows on every later migration pass — and on the","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/schema.go#L644-L680","documentation":"This error wraps a failure in ensureBackfilledCustomStatusesCustomTypes, the post-migration backfill that populates custom status/type rows to their canonical values. Main schema migrations have already applied at this point (applied count is still returned), so the database may be partially through the pass when this fires.","triggerScenarios":"Calling MigrateUp/MigrateUpWithLock on a database needing migration where the custom statuses/types backfill INSERT/UPDATE fails - constraint violations from unexpected row data, Dolt write errors, or a working set that cannot be staged/committed.","commonSituations":"Legacy databases with hand-edited issue types/statuses that violate backfill expectations; read-only or concurrently-written databases mid-pass; interrupted earlier passes leaving unexpected rows.","solutions":["Inspect the wrapped cause for the exact failing backfill statement/row","Fix or normalize the offending custom status/type rows, then re-run MigrateUp (passes are idempotent)","Ensure the database is opened read-write with no concurrent writers during the pass","If a previous pass crashed mid-backfill, re-running MigrateUp should resume/complete it; restore from a Dolt commit if state is inconsistent"],"exampleFix":"// before: ignoring the error and opening anyway\n_, _ = schema.MigrateUp(ctx, db)\n// after: fail fast and keep the applied count\napplied, err := schema.MigrateUp(ctx, db)\nif err != nil {\n    return fmt.Errorf(\"open aborted after %d migrations: %w\", applied, err)\n}","handlingStrategy":"try-catch","validationCode":"// Sanity-check custom statuses/types tables exist and are writable before migrating\nfor _, t := range []string{\"issue_statuses\", \"issue_types\"} {\n    if _, err := db.QueryContext(ctx, \"SELECT 1 FROM \"+t+\" LIMIT 1\"); err != nil {\n        return fmt.Errorf(\"%s unreadable: %w\", t, err)\n    }\n}","typeGuard":"func isBackfillErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"backfill custom tables\")\n}","tryCatchPattern":"applied, err := schema.MigrateUp(ctx, db)\nif isBackfillErr(err) {\n    return fmt.Errorf(\"migration partially applied (%d); fix backfill cause and re-run: %w\", applied, err)\n}","preventionTips":["Do not hand-edit custom status/type rows to values outside the allowed set","Re-run MigrateUp after any interrupted pass; backfills are idempotent","Open the database read-write when upgrades are expected"],"tags":["database","migration","backfill","dolt"],"backgroundTag":"migration-backfill-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}