gastownhall/beads · error
failed to commit orphaned dependency removals
Error message
failed to commit orphaned dependency removals: %w
What it means
After deleting orphaned dependency rows inside an explicit transaction, OrphanedDependencies calls tx.Commit(). Because Dolt may run with autocommit disabled, this commit is what makes the deletions durable — if it fails, the wrapped error is returned and none of the removals are persisted (the transaction rolls back). This error appears only after individual DELETEs succeeded on the connection.
Solutions
- Re-run `bd doctor --fix` after confirming the Dolt server is healthy — the transaction rolled back, so the fix is safely repeatable.
- Check server logs and disk space; resolve storage errors (disk full, corrupted sstables) before retrying.
- Ensure no other session holds locks on dependencies/wisp_dependencies (lock wait timeout); close competing bd processes.
- If the server runs with --no-auto-commit, verify it accepts explicit commits and isn't in a read-only or shutting-down state.
Example fix
// before: server dropped connection during DELETE loop
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit orphaned dependency removals: %w", err)
}
// after: restart dolt server, ensure free disk, then re-run the fix
// dolt server & # healthy restart; orphan removals are re-applied from scratch
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit orphaned dependency removals: %w", err) // succeeds
} Defensive patterns
Strategy: retry
Validate before calling
// check free disk and server health before running deletions
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("server unhealthy before fix: %w", err)
}
// and on the host: df -h <dolt_data_dir> Type guard
var lockErr *driver.Error
if errors.As(err, &lockErr) && (lockErr.Number == 1205 || lockErr.Number == 1213) {
// lock wait timeout / deadlock — wait and retry the fix
} Try / catch
if err := fix.OrphanedDependencies(path, verbose); err != nil {
if strings.Contains(err.Error(), "failed to commit") {
// transaction rolled back; nothing persisted — safe to re-run
time.Sleep(2 * time.Second)
err = fix.OrphanedDependencies(path, verbose)
}
if err != nil {
log.Fatalf("orphan removals not committed: %v", err)
}
} Prevention
- Ensure ample free disk space on the Dolt data directory before large fixes.
- Close competing bd processes/sessions to avoid lock-wait timeouts during the DELETE loop.
- Run with autocommit semantics understood: with --no-auto-commit servers, only Commit persists, so verify server health beforehand.
- Re-run after failure — the transaction rolls back, so the fix is idempotent.
When it happens
Trigger: tx.Commit() fails at validation.go:108 — the connection to the Dolt server dropped during the DELETE loop, the server rejected the commit (e.g. storage error, deadlock/lock wait timeout, server shutting down with --no-auto-commit), or the transaction was already invalidated by an earlier session-level error.
Common situations: Dolt server killed mid-fix so buffered writes can't be committed; disk-full or storage backend failure on the server; lock conflicts with another session holding row/table locks on `dependencies`/`wisp_dependencies`; long DELETE loop exceeding a lock-wait timeout before Commit.
Related errors
- ErrTransaction
- failed to begin transaction
- failed to begin transaction
- failed to commit cross-table duplicate removals
- failed to commit dependency key repairs
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/7c583d8338f5c9b9.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/bd/doctor/fix/validation.go:109
case "dependencies":
_, err = tx.Exec("DELETE FROM dependencies WHERE issue_id = ? AND "+fixDependencyTargetExpr+" = ?", o.issueID, o.dependsOnID)
case "wisp_dependencies":
_, err = tx.Exec("DELETE FROM wisp_dependencies WHERE issue_id = ? AND "+fixDependencyTargetExpr+" = ?", o.issueID, o.dependsOnID)
default:
fmt.Printf(" Warning: skipped orphaned dependency from unexpected table %s\n", o.depTable)
continue
}
if err != nil {
fmt.Printf(" Warning: failed to remove %s→%s: %v\n", o.issueID, o.dependsOnID, err)
} else {
removed++
if showIndividual {
fmt.Printf(" Removed orphaned dependency: %s→%s\n", o.issueID, o.dependsOnID)
}
}
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit orphaned dependency removals: %w", err)
}
// Commit changes in Dolt
_, _ = db.Exec("CALL DOLT_COMMIT('-Am', 'doctor: remove orphaned dependencies')") // Best effort: commit advisory; schema fix already applied in-memory
fmt.Printf(" Fixed %d orphaned dependency reference(s)\n", removed)
return nil
}
// ChildParentDependencies removes child→parent blocking dependencies.
// These often indicate a modeling mistake (deadlock: child waits for parent, parent waits for children).
// Requires explicit opt-in via --fix-child-parent flag since some workflows may use these intentionally.
// If verbose is true, prints each removed dependency; otherwise shows only summary.
func ChildParentDependencies(path string, verbose bool) error {
beadsDir, err := resolvedWorkspaceBeadsDir(path)
if err != nil {
return err
}View on GitHub (pinned to 71377f2769)