gastownhall/beads · error

flatten step %q: %w

Error message

flatten step %q: %w

What it means

Inside Flatten, each squashing step (create temp branch, checkout, soft reset, commit, checkout main, hard reset, delete branch) is executed via an ExecContext helper that wraps failures as "flatten step \"<name>\": %w". The step name identifies exactly which stored procedure failed.

Source

Thrown at internal/storage/versioncontrolops/flatten.go:46

		"SELECT commit_hash FROM dolt_log ORDER BY date ASC LIMIT 1",
	).Scan(&initialHash); err != nil {
		return fmt.Errorf("find initial commit: %w", err)
	}

	// Count commits to check if flatten is needed.
	var commitCount int
	if err := conn.QueryRowContext(ctx,
		"SELECT COUNT(*) FROM dolt_log",
	).Scan(&commitCount); err != nil {
		return fmt.Errorf("count commits: %w", err)
	}
	if commitCount <= 1 {
		return nil // already flat
	}

	execSQL := func(name, query string, args ...interface{}) error {
		if _, err := conn.ExecContext(ctx, query, args...); err != nil {
			return fmt.Errorf("flatten step %q: %w", name, err)
		}
		return nil
	}

	steps := []struct {
		name  string
		query string
		args  []interface{}
	}{
		{"create temp branch", "CALL DOLT_BRANCH('flatten-tmp')", nil},
		{"checkout temp branch", "CALL DOLT_CHECKOUT('flatten-tmp')", nil},
		{"soft reset to initial", "CALL DOLT_RESET('--soft', ?)", []interface{}{initialHash}},
		{"commit flattened snapshot", "CALL DOLT_COMMIT('-Am', 'flatten: squash all history into single commit')", nil},
		{"checkout main", "CALL DOLT_CHECKOUT('main')", nil},
		{"reset main to flattened", "CALL DOLT_RESET('--hard', 'flatten-tmp')", nil},
		{"delete temp branch", "CALL DOLT_BRANCH('-D', 'flatten-tmp')", nil},
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the quoted step name in the error to identify which stored procedure failed and address its specific cause.
  2. Delete the leftover 'flatten-tmp' branch (CALL DOLT_BRANCH('-D', 'flatten-tmp')) if a prior run crashed at branch creation.
  3. Ensure the working set is clean (WorkingSetClean) so DOLT_CHECKOUT/DOLT_COMMIT succeed.
  4. Use a single dedicated connection, not a pool — session-scoped state (current branch) must persist across steps.
  5. After a successful flatten, run PruneRemoteRefs and DoltGC per the docs to reclaim space.

Example fix

// before
versioncontrolops.Flatten(ctx, sqlDB) // fails at "checkout temp branch"
// after
clean, err := versioncontrolops.WorkingSetClean(ctx, conn)
if err != nil || !clean { return fmt.Errorf("commit or stash before flatten") }
conn.ExecContext(ctx, "CALL DOLT_BRANCH('-D', 'flatten-tmp')") // clear stale branch from crashed run
versioncontrolops.Flatten(ctx, singleConn)
Defensive patterns

Strategy: try-catch

Validate before calling

clean, err := versioncontrolops.WorkingSetClean(ctx, conn)
if err != nil { return err }
if !clean { return fmt.Errorf("commit changes before flatten") }
// remove leftovers from a previously crashed run
conn.ExecContext(ctx, "CALL DOLT_BRANCH('-D', 'flatten-tmp')")

Try / catch

err := versioncontrolops.Flatten(ctx, conn)
if err != nil {
    var stepName string
    if _, scanErr := fmt.Sscanf(err.Error(), "flatten step %q", &stepName); scanErr == nil {
        return fmt.Errorf("flatten failed at %q; database may be mid-sequence, inspect branches: %w", stepName, err)
    }
    return err
}

Prevention

When it happens

Trigger: Any of the seven steps failing: DOLT_BRANCH when 'flatten-tmp' already exists from a previous crashed run; DOLT_CHECKOUT failing due to dirty working set; DOLT_RESET/DOLT_COMMIT failing on a pooled connection that lost session-scoped branch state; conflict or unknown ref passed to a step.

Common situations: A prior Flatten attempt crashed leaving 'flatten-tmp' behind; caller passed a pooled *sql.DB so CHECKOUT affects a different session's connection; uncommitted changes blocking checkout; interrupted run mid-sequence.

Related errors


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