gastownhall/beads · error
scan %s constraint violation: %w
Error message
scan %s constraint violation: %w
What it means
While inspecting per-table violation rows, a row could not be scanned into (violation_type string, violation_info any). This means the row shape or types deviate from what the two-destination Scan expects. The check aborts with this wrapped error, blocking the auto-repair (which requires proving all violations are FK-only).
Source
Thrown at internal/storage/versioncontrolops/mergesettle.go:937
// violationsAreIssueFKOnly reports whether every constraint violation recorded
// for table is a foreign-key violation referencing issues — the only class the
// cascade repair understands. violation_info is Dolt's JSON descriptor; its
// ReferencedTable names the FK's parent.
func violationsAreIssueFKOnly(ctx context.Context, db DBConn, table string) (bool, error) {
// table is from the fixed fkCascadeRepairDeletes allowlist, never user input.
//nolint:gosec // G202: hardcoded table name.
rows, err := db.QueryContext(ctx,
"SELECT violation_type, violation_info FROM dolt_constraint_violations_"+table)
if err != nil {
return false, fmt.Errorf("query %s constraint violations: %w", table, err)
}
defer rows.Close()
for rows.Next() {
var vtype string
var vinfo any
if err := rows.Scan(&vtype, &vinfo); err != nil {
return false, fmt.Errorf("scan %s constraint violation: %w", table, err)
}
if vtype != "foreign key" {
return false, nil
}
// Server mode returns violation_info as JSON text; the embedded engine
// hands back the driver's native value (e.g. merge.FkCVMeta), which
// marshals to the same JSON.
var infoJSON []byte
switch v := vinfo.(type) {
case []byte:
infoJSON = v
case string:
infoJSON = []byte(v)
default:
b, err := json.Marshal(v)
if err != nil {
return false, nil // unknown descriptor shape — operator decides
}View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped %w error for column count vs type-conversion details.
- Run SELECT violation_type, violation_info FROM dolt_constraint_violations_<table> manually to inspect actual shapes.
- Upgrade beads (or the Dolt engine) so the driver's violation_info encoding matches the code path (JSON text vs native value).
- Until fixed, resolve violations manually rather than via auto-repair.
Example fix
// before
var vtype string
var vinfo any
if err := rows.Scan(&vtype, &vinfo); err != nil {
return false, fmt.Errorf("scan %s constraint violation: %w", table, err)
}
// after: accept either JSON text or native value shapes
var vtype string
var vinfo any
if err := rows.Scan(&vtype, &vinfo); err != nil {
var raw []byte
if serr := rows.Scan(&vtype, &raw); serr != nil {
return false, fmt.Errorf("scan %s constraint violation: %w", table, err)
}
vinfo = string(raw)
} Defensive patterns
Strategy: type-guard
Validate before calling
rows, _ := db.Query("SELECT violation_type, violation_info FROM dolt_constraint_violations_issues LIMIT 1")
cols, _ := rows.Columns()
// proceed only when len(cols) == 2 Type guard
func violationRowShapeMatches(ctx context.Context, db DBConn, table string) bool {
rows, err := db.QueryContext(ctx, "SELECT violation_type, violation_info FROM dolt_constraint_violations_"+table+" LIMIT 1")
if err != nil {
return false
}
defer rows.Close()
c, _ := rows.Columns()
return len(c) == 2
} Try / catch
ok, err := violationsAreIssueFKOnly(ctx, db, t)
if err != nil && strings.Contains(err.Error(), "scan") {
// violation_info encoding drift: fall back to manual resolution
return manualFKResolution(t)
} Prevention
- Check rows.Columns() shape before scanning system tables
- Handle both JSON-text and native violation_info encodings
- Test pulls across engine version upgrades
When it happens
Trigger: A violations row returns a violation_type that is not string-convertible or an unexpected number of columns (engine version changed violation_info encoding), causing rows.Scan to fail.
Common situations: Dolt upgrade changing violation_info from JSON text to a structured native driver value (or vice versa); server vs embedded engine returning different driver value types; corrupt violation metadata.
Related errors
- scan constraint violation: %w
- iter dependents: scan: %w
- iter issues: scan: %w
- query constraint violations: %w
- scan constraint violation: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a6f01ab6763fbac4.
Report an issue: GitHub.