{"record":{"id":"2df98caf265c51de","repo":"gastownhall/beads","slug":"clearing-partial-0040-nonlocal-rows-w","errorCode":null,"errorMessage":"clearing partial 0040 nonlocal rows: %w","messagePattern":"clearing partial 0040 nonlocal rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/migration_repairs.go","lineNumber":124,"sourceCode":"// each paired with its own CALL DOLT_COMMIT. Over a shared sql-server a transient\n// (\"busy buffer\" -> \"bad connection\") can leave some rows committed while the\n// schema_migrations version row never records, so the init retry loop re-runs\n// 0040 from the top and the bare INSERT dies on \"duplicate primary key given:\n// [wisps]\", bricking the database. 0040 is a shipped, content-hashed migration\n// and cannot be edited (see the file header), so instead clear any of those four\n// rows before the replay and commit the removal, leaving 0040's INSERT+COMMIT\n// pairs a clean, real diff. No-op when 0040 never partially applied.\nfunc repairPartial0040NonlocalInsert(ctx context.Context, db DBConn) error {\n\tpresent, err := anyNonlocalFrozenRowPresent(ctx, db)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !present {\n\t\treturn nil\n\t}\n\tif _, err := db.ExecContext(ctx,\n\t\t\"DELETE FROM dolt_nonlocal_tables WHERE table_name IN \"+nonlocalFrozenRowsInList); err != nil {\n\t\treturn fmt.Errorf(\"clearing partial 0040 nonlocal rows: %w\", err)\n\t}\n\tif err := commitNonlocalRepair(ctx, db,\n\t\t\"repair: clear partial 0040 nonlocal rows before replay\"); err != nil {\n\t\treturn fmt.Errorf(\"committing 0040 nonlocal repair: %w\", err)\n\t}\n\treturn nil\n}\n\n// repairPartial0041NonlocalDelete heals a partially-applied migration 0041 so\n// its shipped body can replay. 0041 begins by clearing dolt_nonlocal_tables and\n// committing (\"disable nonlocal tables for fk migrations\"). If a transient\n// interrupts 0041 after that commit but before its version row records, the\n// retry re-runs 0041 against an already-empty table: the DELETE stages nothing\n// and the paired DOLT_COMMIT (no --skip-empty in the shipped bytes) fails with\n// \"nothing to commit\". Restore the pre-0041 invariant — the four rows 0040\n// leaves — so the frozen DELETE+COMMIT has a real diff again. No-op when those\n// rows are already present (the common path).\nfunc repairPartial0041NonlocalDelete(ctx context.Context, db DBConn) error {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/migration_repairs.go#L106-L142","documentation":"repairPartial0040NonlocalInsert deletes the four frozen dolt_nonlocal_tables rows before replaying shipped migration 0040 (which bare-INSERTs them, dying on duplicate keys after a partial apply). This error wraps failure of that cleanup DELETE — connection drop, table missing, or another SQL-level error while clearing the partially-applied rows.","triggerScenarios":"bd init re-running 0040 after a transient left some rows committed but the schema_migrations version row unrecorded, and the cleanup DELETE fails — typically another connection drop, the table being absent, or lock contention from a concurrent bd process.","commonSituations":"Flaky network to a shared Dolt sql-server during upgrade; repeated init retries on a bricked database; concurrent bd processes on the same database.","solutions":["Retry bd init — the repair re-runs and is idempotent","Ensure no other bd process is concurrently mutating the database","Stabilize connectivity to the Dolt sql-server and retry","Inspect the wrapped error for the underlying SQL cause (missing table → schema drift needing manual restore)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify the frozen-row state before the repair fires\nvar count int\ndb.QueryRowContext(ctx, \"SELECT COUNT(*) FROM dolt_nonlocal_tables WHERE table_name IN ('wisps','wisp_*','repo_mtimes','local_metadata')\").Scan(&count)\n// count > 0 means the 0040 partial-apply heal will run","typeGuard":null,"tryCatchPattern":"if err := repairPartial0040NonlocalInsert(ctx, db); err != nil {\n    if isTransient(err) {\n        return repairPartial0040NonlocalInsert(ctx, db) // idempotent\n    }\n    return fmt.Errorf(\"0040 repair failed: %w\", err)\n}","preventionTips":["Retry init — the delete-then-replay repair is safe to re-run","Ensure exclusive database access during migrations (no parallel bd runs)","Stabilize connectivity to shared Dolt servers before upgrading","Back up the database before major version upgrades"],"tags":["dolt","migration","storage","transient"],"backgroundTag":"migration-partial-apply","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}