{"record":{"id":"76376362daf9cd40","repo":"gastownhall/beads","slug":"staging-s-w","errorCode":null,"errorMessage":"staging %s: %w","messagePattern":"staging (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/migration_repairs.go","lineNumber":84,"sourceCode":"// repairs, which normalise the table to the exact state each shipped\n// (content-hashed, un-editable) migration body expects before it runs.\nconst nonlocalTablesName = \"dolt_nonlocal_tables\"\nconst nonlocalFrozenRowsInList = \"('wisps', 'wisp_*', 'repo_mtimes', 'local_metadata')\"\nconst nonlocalFrozenRowsValues = \"('wisps', 'main', 'immediate'), ('wisp_*', 'main', 'immediate'), \" +\n\t\"('repo_mtimes', 'main', 'immediate'), ('local_metadata', 'main', 'immediate')\"\n\n// commitNonlocalRepair commits a version-40/41 repair's edit to\n// dolt_nonlocal_tables, staging that table BY NAME rather than with\n// DOLT_COMMIT('-Am', ...). The scoping is load-bearing: on the bounded-migrate\n// path (upTo != 0, where per-step commit is off) migrations 1..upTo sit\n// uncommitted in the working set while the repair runs, and an \"add all\"\n// commit here would sweep all of them into a repair-labeled commit. Staging\n// only the table the repair touched leaves the rest of the working set exactly\n// as the pass expects to find it. --skip-empty keeps the commit a clean no-op\n// if the edit staged nothing.\nfunc commitNonlocalRepair(ctx context.Context, db DBConn, message string) error {\n\tif err := DrainCall(ctx, db, \"CALL DOLT_ADD(?)\", nonlocalTablesName); err != nil {\n\t\treturn fmt.Errorf(\"staging %s: %w\", nonlocalTablesName, err)\n\t}\n\treturn DrainCall(ctx, db, \"CALL DOLT_COMMIT('-m', ?, '--skip-empty')\", message)\n}\n\n// anyNonlocalFrozenRowPresent reports whether any of 0040's four\n// dolt_nonlocal_tables rows currently exists (in the working set), the signal\n// the version-40/41 repairs use to decide whether a heal is needed. Guarding on\n// it keeps both repairs a strict no-op on the common (non-partial) path, so a\n// fresh init reaches 0040/0041 having done no repair work at all — the repairs\n// only ever touch a database that actually took the partial-apply brick.\nfunc anyNonlocalFrozenRowPresent(ctx context.Context, db DBConn) (bool, error) {\n\tvar count int\n\tif err := db.QueryRowContext(ctx,\n\t\t\"SELECT COUNT(*) FROM dolt_nonlocal_tables WHERE table_name IN \"+nonlocalFrozenRowsInList).Scan(&count); err != nil {\n\t\treturn false, fmt.Errorf(\"counting nonlocal frozen rows: %w\", err)\n\t}\n\treturn count > 0, nil\n}","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/migration_repairs.go#L66-L102","documentation":"commitNonlocalRepair stages dolt_nonlocal_tables via CALL DOLT_ADD and commits with DOLT_COMMIT --skip-empty as part of healing partially-applied migrations 0040/0041. This error wraps a failure of the DOLT_ADD staging call itself. It means the Dolt stored-procedure call errored — connection drop, server-side procedure failure, or a non-committable working set.","triggerScenarios":"Running bd init/migrations over a flaky shared sql-server where the connection drops mid-repair (\"busy buffer\" -> \"bad connection\"); dolt_nonlocal_tables missing or corrupted; Dolt server rejecting CALL DOLT_ADD while repairing 0040 or 0041.","commonSituations":"Transient network interruptions to a shared Dolt sql-server during upgrade; database partially bricked by a prior interrupted migration; Dolt server/client version mismatch.","solutions":["Retry bd init — the repair is idempotent and guarded by anyNonlocalFrozenRowPresent","Verify connectivity to the Dolt sql-server and overall health (bd doctor)","Check that dolt_nonlocal_tables exists and the working set is not conflicted","Inspect the wrapped underlying error (%w) for the real Dolt/SQL cause"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before running migrations, confirm the server accepts queries\nvar one int\nif err := db.QueryRowContext(ctx, \"SELECT 1\").Scan(&one); err != nil {\n    return fmt.Errorf(\"dolt server unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := runMigrations(ctx, db); err != nil {\n    if isTransient(err) { // bad connection / busy buffer\n        return runMigrations(ctx, db) // repairs are idempotent and presence-guarded\n    }\n    return err\n}","preventionTips":["Run bd init against a stable, local-first Dolt connection rather than a flaky shared sql-server","Retry init on transient connection errors — all repairs are idempotent","Keep Dolt server/client versions aligned","Avoid concurrent bd processes against the same database during migrations"],"tags":["dolt","migration","storage","transient"],"backgroundTag":"dolt-procedure-call-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}