gastownhall/beads · error

scan schema conflict: %w

Error message

scan schema conflict: %w

What it means

While iterating dolt_schema_conflicts rows, a row's table_name value could not be scanned into a Go string — the value was NULL or of an unexpected column type. This usually indicates engine/version drift or a corrupted schema-conflict record, not a normal operating condition.

Source

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

	return merging, nil
}

// schemaConflictTables lists the tables whose SCHEMAS conflict — dolt keeps
// them out of dolt_conflicts entirely, so totalConflicts cannot see them.
func schemaConflictTables(ctx context.Context, db DBConn) ([]string, error) {
	rows, err := db.QueryContext(ctx, "SELECT table_name FROM dolt_schema_conflicts")
	if err != nil {
		if isMissingSystemTable(err) {
			return nil, nil
		}
		return nil, fmt.Errorf("query schema conflicts: %w", err)
	}
	defer func() { _ = rows.Close() }()
	var tables []string
	for rows.Next() {
		var t string
		if err := rows.Scan(&t); err != nil {
			return nil, fmt.Errorf("scan schema conflict: %w", err)
		}
		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

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect dolt_schema_conflicts manually (SELECT *) to find the row with a NULL/unusual table_name and fix or clear it.
  2. Resolve the underlying schema conflict properly so the offending row is removed and rewritten.
  3. Check dolt engine version compatibility; upgrade bd or dolt so the expected table layout matches.
  4. If the state is corrupt, abort the merge and redo it after schema alignment.

Example fix

// before: scanning directly into string, NULL fails the scan
var t string
if err := rows.Scan(&t); err != nil { ... }
// after: tolerant scan for nullability/type drift
var t sql.NullString
if err := rows.Scan(&t); err != nil { ... }
if !t.Valid { continue } // skip malformed row, report separately
Defensive patterns

Strategy: type-guard

Validate before calling

// Detect malformed rows before relying on the scan:
rows, _ := db.QueryContext(ctx, "SELECT table_name FROM dolt_schema_conflicts")
for rows.Next() {
  var t sql.NullString
  if rows.Scan(&t) != nil || !t.Valid { /* corrupt row; inspect via SELECT * */ }
}

Type guard

func validSchemaConflictRow(t sql.NullString) bool { return t.Valid && strings.TrimSpace(t.String) != "" }

Try / catch

if err != nil && strings.Contains(err.Error(), "scan schema conflict") {
  log.Printf("malformed dolt_schema_conflicts row: %v — inspect table manually", err)
}

Prevention

When it happens

Trigger: GetMergeBlockers iterating schema conflict rows where a row's table_name is NULL or of an unexpected type — typically after a dolt engine upgrade/change, a corrupted record, or querying a database whose dolt_schema_conflicts layout differs from what bd expects.

Common situations: Mixed dolt versions between what created the merge state and what reads it; manually edited or corrupted dolt metadata; third-party tools writing into dolt system tables.

Related errors


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