gastownhall/beads · error
clear conflict for issue %v: %w
Error message
clear conflict for issue %v: %w
What it means
The merged values were written successfully, but the DELETE from dolt_conflicts_issues that marks the row as settled failed with a driver/database error. The delete is what tells Dolt the conflict is resolved, so the merge cannot proceed: the UPDATE has been applied but the conflict row remains, leaving the merge in a partially-resolved state reported by this wrapped error.
Source
Thrown at internal/storage/versioncontrolops/automerge.go:624
// clearing the conflict now would discard their side undetectably.
// But RowsAffected is rows CHANGED, not rows MATCHED: the DSN does
// not set clientFoundRows (doltutil/dsn.go), so a write the backend
// normalizes to the bytes already stored also reports zero. Only a
// follow-up existence check can tell "vanished" from "no-op".
if n, err := res.RowsAffected(); err != nil || n == 0 {
present, err := conflictTargetStillPresent(ctx, db, "issues", issuesKeyColumn, m.ourKey)
if err != nil {
return fmt.Errorf("confirm issue %v still exists after writing merged values: %w", m.ourKey, err)
}
if !present {
return fmt.Errorf("merged values for issue %v matched no row (was it deleted concurrently?); conflict left unresolved", m.ourKey)
}
}
}
res, err := db.ExecContext(ctx,
"DELETE FROM dolt_conflicts_issues WHERE our_"+issuesKeyColumn+" = ?", m.ourKey)
if err != nil {
return fmt.Errorf("clear conflict for issue %v: %w", m.ourKey, err)
}
if n, err := res.RowsAffected(); err == nil && n == 0 {
return fmt.Errorf("conflict for issue %v was not cleared (no conflict row deleted)", m.ourKey)
}
}
return nil
}
// unionConflictsAreSafe reports whether every live conflict of a union-merged
// table (labels, comments, events) is the same row on both sides with matching
// columns — the only class where "union" has an unambiguous answer. A row
// missing on one side (a deletion racing an insert) or diverging columns in a
// supposedly immutable row goes to the operator.
func unionConflictsAreSafe(ctx context.Context, db DBConn, table string) ([]unionRowKey, bool, error) {
keyCols, ok := unionConflictKeyColumns[table]
if !ok {
return nil, false, fmt.Errorf("table %s is not union-mergeable", table)
}View on GitHub (pinned to 71377f2769)
Solutions
- Re-run the merge/auto-resolve: the plan is recomputed from the (still-present) conflict row and both UPDATE and DELETE are re-executed idempotently.
- Verify the Dolt server is reachable and supports the manual conflict-resolution path (`dolt version`, upgrade if old).
- Check for competing `bd` processes touching the same database; serialize them and retry.
- If the connection user lacks DELETE privilege on dolt_conflicts_issues, grant it or run the merge with an account that has it.
- As a last resort, resolve the conflict manually via DOLT_CONFLICTS_RESOLVE for the issues table.
Defensive patterns
Strategy: retry
Validate before calling
// confirm conflict tables are writable before starting resolution
_, err := db.ExecContext(ctx,
"SELECT COUNT(*) FROM dolt_conflicts_issues LIMIT 1")
if err != nil {
return fmt.Errorf("conflict table unreadable before merge: %w", err)
} Try / catch
if err := TryAutoResolveMergeConflicts(ctx, db); err != nil {
if strings.Contains(err.Error(), "clear conflict for issue") {
// partial resolution: values written, conflict row remains — safe to retry
time.Sleep(time.Second)
return TryAutoResolveMergeConflicts(ctx, db)
}
return err
} Prevention
- Ensure DELETE privileges on dolt_conflicts_issues for the merge user
- Use a current dolt version; old servers may reject conflict-table writes at certain merge phases
- Do not stop the Dolt server between the UPDATE and DELETE phases of resolution
- Retry auto-resolution — it is idempotent because the conflict row still drives the plan
When it happens
Trigger: db.ExecContext on `DELETE FROM dolt_conflicts_issues WHERE our_<key> = ?` fails — connection dropped after the UPDATE, the dolt_conflicts_issues system table is locked or unwritable (e.g. conflict metadata not flushed), the database entered a read-only state, or the dolt version in use rejects writes to conflict tables at that point in the merge.
Common situations: Remote Dolt server connection dies mid-resolution; another session concurrently manipulating conflicts locks the table; running a newer/older dolt version whose conflict-table semantics differ; transaction aborted by a concurrent schema change between UPDATE and DELETE.
Related errors
- apply merged values for issue %v: %w
- confirm issue %v still exists after writing merged values: %
- merged values for issue %v matched no row (was it deleted co
- conflict for issue %v was not cleared (no conflict row delet
- ErrTransaction
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b8425f3463bd9e37.
Report an issue: GitHub.