gastownhall/beads · error

query merge status: %w

Error message

query merge status: %w

What it means

mergeInProgress queries the dolt system table dolt_merge_status for is_merging; this error wraps any failure other than the table being absent or empty (those are treated as 'not merging'). It surfaces when the GetMergeBlockers diagnostic cannot read merge state at all.

Source

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

	} else {
		out.ConstraintViolations = violations
	}
	// Partial results are still useful — the caller gets what was readable
	// plus the reason the rest was not.
	return out, errors.Join(errs...)
}

// mergeInProgress reads dolt_merge_status.is_merging: true between a halted
// DOLT_MERGE and its concluding commit. It is what lets `--conclude` tell
// "resolved but uncommitted" apart from "nothing to conclude".
func mergeInProgress(ctx context.Context, db DBConn) (bool, error) {
	var merging bool
	err := db.QueryRowContext(ctx, "SELECT is_merging FROM dolt_merge_status").Scan(&merging)
	if err != nil {
		if isMissingSystemTable(err) || errors.Is(err, sql.ErrNoRows) {
			return false, nil
		}
		return false, fmt.Errorf("query merge status: %w", err)
	}
	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

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped cause: if it is 'unknown column is_merging', align the dolt engine version with what bd expects.
  2. Verify you are connected to a dolt database, not plain MySQL, and that it is not mid-migration.
  3. Restart the dolt sql-server (or reopen the embedded DB) to release locks, then rerun the blocker check.
  4. If persistent, file an issue with the wrapped error text — the helper tolerates missing tables but not broken ones.

Example fix

// before: treating any failure as fatal
blockers, err := ops.GetMergeBlockers(ctx, db)
if err != nil { return err }
// after: distinguish version drift from transient failure
if strings.Contains(err.Error(), "is_merging") {
  log.Printf("dolt version drift: %v — check engine compatibility", err)
} else if isTransient(err) {
  blockers, err = retryMergeBlockers(ctx, db)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check that the merge status table is queryable:
var merging bool
err := db.QueryRowContext(ctx, "SELECT is_merging FROM dolt_merge_status").Scan(&merging)
if err != nil && !missingTable(err) && !errors.Is(err, sql.ErrNoRows) {
  // degraded diagnosis; warn or skip before calling GetMergeBlockers
}

Try / catch

blockers, err := ops.GetMergeBlockers(ctx, db)
if err != nil {
  if strings.Contains(err.Error(), "query merge status") {
    log.Printf("merge status unreadable, continuing with partial blockers: %v", err)
  } else { return err }
}

Prevention

When it happens

Trigger: GetMergeBlockers run against a database where dolt_merge_status exists but the query fails: SQL error from the embedded engine or sql-server, corrupted/locked merge state, permission denial, or a dolt version where dolt_merge_status lacks the is_merging column.

Common situations: Pointing bd at a non-dolt MySQL database (schema drift); an old or newer dolt version with a changed system-table layout; a hung merge holding locks on the status table.

Related errors


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