gastownhall/beads · error
query dependency conflicts: %w
Error message
query dependency conflicts: %w
What it means
dependencyConflictsAreAuditOnly queries dolt_conflicts_dependencies to decide whether every dependency-table conflict is the same logical edge differing only in audit fields (safe to auto-resolve) or a real add/delete conflict (needs an operator). This error wraps any SQL failure of that SELECT — the audit check itself failed, so the caller conservatively treats the conflicts as non-auto-resolvable.
Source
Thrown at internal/storage/versioncontrolops/mergesettle.go:609
// It does NOT trust the primary key as proof of a shared edge. With deterministic
// ids the same edge has the same id on every clone, but an issue rename can leave a
// row's surrogate id stale (depid.New(oldID, target)) while issue_id/target have
// already moved (#4259 finding 2), so two genuinely different edges could collide on
// one id. We therefore verify the natural identity — issue_id and the resolved
// target — matches on both sides, and that the type matches, before declaring the
// conflict audit-only. It returns false if any conflicted row differs in identity or
// type, or was deleted on one side (an add/delete conflict).
func dependencyConflictsAreAuditOnly(ctx context.Context, db DBConn) (bool, error) {
rows, err := db.QueryContext(ctx, `
SELECT our_id, their_id,
our_issue_id, their_issue_id,
our_depends_on_issue_id, their_depends_on_issue_id,
our_depends_on_wisp_id, their_depends_on_wisp_id,
our_depends_on_external, their_depends_on_external,
our_type, their_type
FROM dolt_conflicts_dependencies`)
if err != nil {
return false, fmt.Errorf("query dependency conflicts: %w", err)
}
defer rows.Close()
for rows.Next() {
var (
ourID, theirID sql.NullString
ourIssue, theirIssue sql.NullString
ourDepIssue, theirDepIssue sql.NullString
ourDepWisp, theirDepWisp sql.NullString
ourDepExt, theirDepExt sql.NullString
ourType, theirType sql.NullString
)
if err := rows.Scan(&ourID, &theirID, &ourIssue, &theirIssue,
&ourDepIssue, &theirDepIssue, &ourDepWisp, &theirDepWisp,
&ourDepExt, &theirDepExt, &ourType, &theirType); err != nil {
return false, fmt.Errorf("scan dependency conflict: %w", err)
}
// One side deleted the edge (add/delete conflict): leave for the operator.View on GitHub (pinned to 71377f2769)
Solutions
- Verify an active merge exists (dolt_status shows conflicts) before the audit query runs; the dolt_conflicts_dependencies table only exists during a conflicted merge.
- Compare the local dolt_conflicts_dependencies schema (DESCRIBE) against the column list the query selects; align the query or upgrade Dolt.
- Check connectivity to the Dolt server and retry if the error is a transient driver/network failure.
- Read the wrapped inner error — unknown table vs unknown column vs connection error each point to a different fix.
Example fix
// before
rows, err := db.QueryContext(ctx, "SELECT ... FROM dolt_conflicts_dependencies")
if err != nil {
return false, fmt.Errorf("query dependency conflicts: %w", err)
}
// after
rows, err := db.QueryContext(ctx, "SELECT ... FROM dolt_conflicts_dependencies")
if err != nil {
if isUnknownTableErr(err) {
return false, nil // no merge conflict state: nothing audit-only to check
}
return false, fmt.Errorf("query dependency conflicts: %w", err)
} Defensive patterns
Strategy: fallback
Validate before calling
var inMerge bool err := db.QueryRowContext(ctx, "SELECT COUNT(*) > 0 FROM dolt_status WHERE staged = 0 AND status LIKE '%conflict%'").Scan(&inMerge) // only run dependencyConflictsAreAuditOnly when conflicts actually exist
Try / catch
auditOnly, err := dependencyConflictsAreAuditOnly(ctx, db)
if err != nil {
if isUnknownTableErr(err) { // dolt_conflicts_dependencies absent: no active conflict state
auditOnly = false // conservative fallback: leave conflicts for operator
} else if isTransientNetErr(err) {
auditOnly, err = dependencyConflictsAreAuditOnly(ctx, db) // retry once
}
} Prevention
- Treat any audit-query failure as 'not audit-only' — never auto-resolve on an unknown answer.
- Check that an active merge with dependency conflicts exists before querying the conflicts table.
- Handle unknown-table errors distinctly from unknown-column errors; they imply different Dolt-version fixes.
- Pin the Dolt version in your environment so conflict-table schemas stay stable.
When it happens
Trigger: TryAutoResolveMergeConflicts calls dependencyConflictsAreAuditOnly during a merge with conflicts in the dependencies table, and the SELECT against dolt_conflicts_dependencies fails: the conflict table does not exist (no merge state / different Dolt version), the schema lacks expected our_/their_ columns, or the connection dropped mid-query.
Common situations: Running against an older/newer Dolt whose dolt_conflicts_dependencies schema differs; query executed outside an active merge so the conflicts table is absent; transient network disconnect to the Dolt server mid-merge settlement.
Related errors
- failed to query dolt_status: %w
- descendants: query: %w
- db: ListRemotes: query: %w
- query conflicts for table %s: %w
- clear %s conflict: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/343c6139180b5c67.
Report an issue: GitHub.