gastownhall/beads · error

query constraint violations: %w

Error message

query constraint violations: %w

What it means

constraintViolationCounts reads dolt_constraint_violations for tables with num_violations > 0; this error wraps any query failure that is not the table being absent (missing table is treated as 'no violations'). It means the merge-blocker diagnostic could not read foreign-key/constraint violation state.

Source

Thrown at internal/storage/versioncontrolops/conflicts.go:525

		tables = append(tables, t)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate schema conflicts: %w", err)
	}
	return tables, nil
}

// constraintViolationCounts lists the tables carrying outstanding constraint
// violations. mergesettle.go repairs the FK-cascade class on the auto path;
// anything it declined lands here, blocking the commit.
func constraintViolationCounts(ctx context.Context, db DBConn) ([]storage.ConstraintViolation, error) {
	rows, err := db.QueryContext(ctx,
		"SELECT `table`, num_violations FROM dolt_constraint_violations WHERE num_violations > 0")
	if err != nil {
		if isMissingSystemTable(err) {
			return nil, nil
		}
		return nil, fmt.Errorf("query constraint violations: %w", err)
	}
	defer func() { _ = rows.Close() }()
	var out []storage.ConstraintViolation
	for rows.Next() {
		var v storage.ConstraintViolation
		if err := rows.Scan(&v.Table, &v.Count); err != nil {
			return nil, fmt.Errorf("scan constraint violation: %w", err)
		}
		out = append(out, v)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate constraint violations: %w", err)
	}
	return out, nil
}

// isMissingSystemTable reports whether err is dolt/MySQL's "table does not
// exist". Matched on the message because the embedded engine and the MySQL

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix the wrapped cause: restore connectivity or grant SELECT on dolt_constraint_violations to the user.
  2. If the error mentions unknown columns, align the dolt engine version with what bd expects.
  3. Retry the blocker check after the merge state stabilizes; mid-merge engine errors are often transient.
  4. Inspect violations directly (SELECT * FROM dolt_constraint_violations WHERE num_violations > 0), repair the FK issues, then conclude the merge.

Example fix

// before: hard-failing the command on a diagnosis query
v, err := ops.GetMergeBlockers(ctx, db)
if err != nil { return err }
// after: log partial errors and still repair readable tables
v, err := ops.GetMergeBlockers(ctx, db)
if err != nil { log.Printf("some blockers unreadable: %v", err) }
for _, cv := range v.ConstraintViolations { repairFK(ctx, cv.Table) }
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the violations table is readable before the full check:
rows, err := db.QueryContext(ctx, "SELECT `table`, num_violations FROM dolt_constraint_violations WHERE num_violations > 0")
if err != nil && !missingTable(err) { /* fix access/version first */ }

Try / catch

blockers, err := ops.GetMergeBlockers(ctx, db)
if err != nil {
  if strings.Contains(err.Error(), "query constraint violations") {
    log.Printf("violations unreadable: %v — continuing with partial blockers", err)
  } else { return err }
}

Prevention

When it happens

Trigger: GetMergeBlockers querying dolt_constraint_violations and receiving a non-missing-table SQL error: connectivity failure, permission denial, engine error while the merge is open, or a dolt version where the table exists but with a different schema (no table/num_violations columns).

Common situations: dolt version drift between the embedded engine's expectations and the actual database; restricted privileges on dolt_* tables in sql-server mode; transient disconnects while diagnosing a stalled merge.

Related errors


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