gastownhall/beads · error
conflict for %s %s carries no their_* data columns
Error message
conflict for %s %s carries no their_* data columns
What it means
When applying the 'theirs' strategy, resolveOneConflictRow collects their_* data columns from the conflict row to write back into the base table; none were found. This means the conflict row carries no transferable their-side data beyond metadata and the key, so there is nothing to apply. Usually indicates an unexpected conflict-table shape or an empty their-side payload.
Source
Thrown at internal/storage/versioncontrolops/conflicts.go:390
// matters, since the delete is what tells dolt the row is settled.
func resolveOneConflictRow(ctx context.Context, db DBConn, table, keyCol, key, strategy string, row rawConflictRow) error {
ourKey, ourOK := row.value("our", keyCol)
theirKey, theirOK := row.value("their", keyCol)
if !ourOK || !theirOK {
return fmt.Errorf("conflict table dolt_conflicts_%s has no our_%s/their_%s column", table, keyCol, keyCol)
}
if ourKey == nil || theirKey == nil {
// delete/modify (one side removed the row) or add/add against a
// missing key: refuse by name. Row-level ours/theirs would silently
// resurrect or destroy a row the operator never looked at.
return fmt.Errorf("conflict for %s %s is not a modify/modify conflict (one side has no row); "+
"resolve it with a whole-table strategy or edit the row directly", table, key)
}
if strategy == ConflictStrategyTheirs {
names, vals := row.theirFields(keyCol)
if len(names) == 0 {
return fmt.Errorf("conflict for %s %s carries no their_* data columns", table, key)
}
sets := make([]string, len(names))
args := make([]any, 0, len(names)+1)
for i, n := range names {
// Column names are interpolated (MySQL cannot bind an
// identifier) and come from the conflict table's own schema,
// which a peer's schema merge can extend — gate them exactly
// like the table name rather than trusting the source.
if err := ValidateConflictTable(n); err != nil {
return fmt.Errorf("refusing to write unexpected column %q of %s: %w", n, table, err)
}
sets[i] = fmt.Sprintf("`%s` = ?", n)
args = append(args, vals[i])
}
args = append(args, ourKey)
stmt := fmt.Sprintf("UPDATE `%s` SET %s WHERE `%s` = ?", table, strings.Join(sets, ", "), keyCol) //nolint:gosec // identifiers validated above
res, err := db.ExecContext(ctx, stmt, args...)
if err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Inspect `SELECT * FROM dolt_conflicts_<table>` to see what their_* columns actually exist
- Check the dolt version; align peers on a version whose conflict-table layout matches this library's expectations
- Fall back to whole-table --theirs resolution, which rebuilds rows from the branch rather than the conflict row
- Abort and redo the merge if the conflict table looks structurally corrupted
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
// verify the conflict row carries their_* data columns before theirs strategy
cols, _ := conflictTableColumns(ctx, db, table)
hasData := false
for _, c := range cols {
if strings.HasPrefix(c, "their_") && !isMetaOrKey(c, keyCol) { hasData = true }
}
if !hasData && strategy == "theirs" { return resolveWholeTable(ctx, db, table, "theirs") } Try / catch
err := resolveOne(ctx, db, table, keyCol, key, "theirs")
if err != nil && strings.Contains(err.Error(), "carries no their_* data columns") {
return resolveWholeTable(ctx, db, table, "theirs")
}
return err Prevention
- Keep dolt versions aligned so conflict-table layouts match expectations
- Avoid dropping all data columns via schema merges on conflicted tables
- Inspect dolt_conflicts_<table> when unsure of its shape
- Default to whole-table strategy for structurally unusual conflicts
When it happens
Trigger: ResolveConflictRows -> resolveOneConflictRow with strategy == theirs calls row.theirFields(keyCol), which filters out our_*, metadata-suffixed columns and the key column; the result is empty, e.g. when the conflict table has only key/metadata columns or column naming deviates from the base_<col>/their_<col> convention.
Common situations: Dolt version whose conflict-table metadata columns are not in the expected suffix set; conflicts created against a table whose data columns were all dropped in a schema merge; manually constructed conflict rows.
Related errors
- failed to recompute is_blocked: %w
- failed to scan comment: %w
- failed to initialize schema: %w
- ignored migrations: %w
- migration %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ed47591fa0697743.
Report an issue: GitHub.