gastownhall/beads · error

clearing partial 0040 nonlocal rows: %w

Error message

clearing partial 0040 nonlocal rows: %w

What it means

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.

Source

Thrown at internal/storage/schema/migration_repairs.go:124

// each paired with its own CALL DOLT_COMMIT. Over a shared sql-server a transient
// ("busy buffer" -> "bad connection") can leave some rows committed while the
// schema_migrations version row never records, so the init retry loop re-runs
// 0040 from the top and the bare INSERT dies on "duplicate primary key given:
// [wisps]", bricking the database. 0040 is a shipped, content-hashed migration
// and cannot be edited (see the file header), so instead clear any of those four
// rows before the replay and commit the removal, leaving 0040's INSERT+COMMIT
// pairs a clean, real diff. No-op when 0040 never partially applied.
func repairPartial0040NonlocalInsert(ctx context.Context, db DBConn) error {
	present, err := anyNonlocalFrozenRowPresent(ctx, db)
	if err != nil {
		return err
	}
	if !present {
		return nil
	}
	if _, err := db.ExecContext(ctx,
		"DELETE FROM dolt_nonlocal_tables WHERE table_name IN "+nonlocalFrozenRowsInList); err != nil {
		return fmt.Errorf("clearing partial 0040 nonlocal rows: %w", err)
	}
	if err := commitNonlocalRepair(ctx, db,
		"repair: clear partial 0040 nonlocal rows before replay"); err != nil {
		return fmt.Errorf("committing 0040 nonlocal repair: %w", err)
	}
	return nil
}

// repairPartial0041NonlocalDelete heals a partially-applied migration 0041 so
// its shipped body can replay. 0041 begins by clearing dolt_nonlocal_tables and
// committing ("disable nonlocal tables for fk migrations"). If a transient
// interrupts 0041 after that commit but before its version row records, the
// retry re-runs 0041 against an already-empty table: the DELETE stages nothing
// and the paired DOLT_COMMIT (no --skip-empty in the shipped bytes) fails with
// "nothing to commit". Restore the pre-0041 invariant — the four rows 0040
// leaves — so the frozen DELETE+COMMIT has a real diff again. No-op when those
// rows are already present (the common path).
func repairPartial0041NonlocalDelete(ctx context.Context, db DBConn) error {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry bd init — the repair re-runs and is idempotent
  2. Ensure no other bd process is concurrently mutating the database
  3. Stabilize connectivity to the Dolt sql-server and retry
  4. Inspect the wrapped error for the underlying SQL cause (missing table → schema drift needing manual restore)
Defensive patterns

Strategy: retry

Validate before calling

// verify the frozen-row state before the repair fires
var count int
db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_nonlocal_tables WHERE table_name IN ('wisps','wisp_*','repo_mtimes','local_metadata')").Scan(&count)
// count > 0 means the 0040 partial-apply heal will run

Try / catch

if err := repairPartial0040NonlocalInsert(ctx, db); err != nil {
    if isTransient(err) {
        return repairPartial0040NonlocalInsert(ctx, db) // idempotent
    }
    return fmt.Errorf("0040 repair failed: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: Flaky network to a shared Dolt sql-server during upgrade; repeated init retries on a bricked database; concurrent bd processes on the same database.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/2df98caf265c51de. Report an issue: GitHub.