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 MySQLView on GitHub (pinned to 71377f2769)
Solutions
- Fix the wrapped cause: restore connectivity or grant SELECT on dolt_constraint_violations to the user.
- If the error mentions unknown columns, align the dolt engine version with what bd expects.
- Retry the blocker check after the merge state stabilizes; mid-merge engine errors are often transient.
- 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
- Grant SELECT on dolt_constraint_violations to the application user.
- Match the dolt engine version to bd's expected schema.
- Repair FK violations promptly (mergesettle auto-path) so the table stays small.
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.