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

  1. 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.
  2. Verify the Dolt server is reachable and supports the manual conflict-resolution path (`dolt version`, upgrade if old).
  3. Check for competing `bd` processes touching the same database; serialize them and retry.
  4. If the connection user lacks DELETE privilege on dolt_conflicts_issues, grant it or run the merge with an account that has it.
  5. 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

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


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