gastownhall/beads · error
backfill content_hash for migration %d: %w
Error message
backfill content_hash for migration %d: %w
What it means
After computing fixes for schema_migrations conflict rows, this code backfills the missing content_hash column by UPDATE-ing each conflicted version with the winning hash. If the UPDATE fails (connection error, lock conflict, engine error), it is wrapped in this message. It indicates the auto-resolve could not normalize the migration table before calling DOLT_CONFLICTS_RESOLVE.
Source
Thrown at internal/storage/versioncontrolops/mergesettle.go:780
for rows.Next() {
var version sql.NullInt64
var ourHash, theirHash sql.NullString
if err := rows.Scan(&version, &ourHash, &theirHash); err != nil {
_ = rows.Close()
return fmt.Errorf("scan schema_migrations conflict: %w", err)
}
if ourHash.String == "" && theirHash.String != "" {
fixes = append(fixes, hashFix{version: version.Int64, hash: theirHash.String})
}
}
if err := errors.Join(rows.Err(), rows.Close()); err != nil {
return err
}
for _, f := range fixes {
if _, err := db.ExecContext(ctx,
"UPDATE schema_migrations SET content_hash = ? WHERE version = ?", f.hash, f.version); err != nil {
return fmt.Errorf("backfill content_hash for migration %d: %w", f.version, err)
}
}
if _, err := db.ExecContext(ctx, "CALL DOLT_CONFLICTS_RESOLVE('--ours', 'schema_migrations')"); err != nil {
return fmt.Errorf("failed to resolve schema_migrations conflicts: %w", err)
}
return nil
}
// resolveConflictDepTarget returns the single non-null dependency target from a
// conflict row's three typed target columns, following the same precedence as
// COALESCE(depends_on_issue_id, depends_on_wisp_id, depends_on_external).
func resolveConflictDepTarget(issueTarget, wispTarget, external sql.NullString) (string, bool) {
switch {
case issueTarget.Valid:
return issueTarget.String, true
case wispTarget.Valid:
return wispTarget.String, true
case external.Valid:View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped driver error for the real cause (unknown column, lock wait timeout, etc.).
- Verify schema_migrations has a content_hash column: SHOW CREATE TABLE schema_migrations.
- Retry the merge after ensuring no other bd/dolt process holds a write transaction on the database.
- If content_hash is missing on one side, reconcile the migration table schema first, then re-run the merge.
Example fix
// before: silent failure path
UPDATE schema_migrations SET content_hash = ? WHERE version = ?
// after: guard existence of the column first
var colCount int
_ = db.QueryRow("SELECT COUNT(*) FROM information_schema.columns WHERE table_name='schema_migrations' AND column_name='content_hash'").Scan(&colCount)
if colCount == 0 {
return fmt.Errorf("schema_migrations.content_hash column missing; run bd migrate repair")
} Defensive patterns
Strategy: try-catch
Validate before calling
var hasCol int
_ = db.QueryRow("SELECT COUNT(*) FROM information_schema.columns WHERE table_name='schema_migrations' AND column_name='content_hash'").Scan(&hasCol)
if hasCol == 0 { /* backfill impossible; repair schema first */ } Try / catch
if err := TryAutoResolveMergeConflicts(ctx, db); err != nil {
if strings.Contains(err.Error(), "backfill content_hash") {
// check locks / column existence, then retry settle once
return retrySettle(ctx, db)
}
return err
} Prevention
- Ensure both clones run the same migration set before pulling
- Avoid concurrent bd processes on the same database
- Verify content_hash column exists on schema_migrations
When it happens
Trigger: The UPDATE ... SET content_hash = ? WHERE version = ? statement fails — e.g. the content_hash column doesn't exist (older schema_migrations layout), the table is locked by another transaction, or the Dolt engine rejects the write mid-merge.
Common situations: Schema drift between clones where one lacks content_hash; a second bd process holding a write lock during merge settlement; embedded-engine transaction conflict on the migrations table.
Related errors
- apply merged values for issue %v: %w
- merge conflicts require resolution (use --strategy ours|thei
- commit conflict resolution: %w
- confirm issue %v still exists after writing merged values: %
- merged values for issue %v matched no row (was it deleted co
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/fda63ab205b2e078.
Report an issue: GitHub.