gastownhall/beads · error

find initial commit: %w

Error message

find initial commit: %w

What it means

Flatten squashes all Dolt commit history into a single commit; it starts by selecting the oldest commit hash from dolt_log. If that query/Scan fails — most commonly sql.ErrNoRows because the database has no commit history, or a connection/availability failure — the error is wrapped as "find initial commit: %w".

Source

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

//  3. Soft-reset to the initial (oldest) commit, collapsing all history
//  4. Stage all + commit as a single snapshot
//  5. Checkout main
//  6. Hard-reset main to the flattened branch
//  7. Delete temp branch
//
// Callers should run PruneRemoteRefs and then DoltGC afterward to reclaim disk
// space from orphaned history — remote-tracking refs still anchor the
// pre-flatten chain, and GC alone reclaims nothing while they exist (bd-agctw).
//
// conn must be a single database connection (not a pooled *sql.DB) since the
// stored procedures rely on session-scoped state (current branch, working set).
func Flatten(ctx context.Context, conn DBConn) error {
	// Find the initial commit hash (oldest ancestor).
	var initialHash string
	if err := conn.QueryRowContext(ctx,
		"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

View on GitHub (pinned to 71377f2769)

Solutions

  1. Ensure the database has at least one commit (make an initial DOLT_COMMIT) before flattening.
  2. Check the wrapped error: sql.ErrNoRows means empty history; others indicate connection problems.
  3. Pass a single dedicated DB connection, not a pooled *sql.DB — Flatten relies on session-scoped state.
  4. Run FlattenDryRun first to get the commit count and initial hash without side effects.

Example fix

// before
versioncontrolops.Flatten(ctx, sqlDB) // pooled DB, possibly empty history
// after
count, _, err := versioncontrolops.FlattenDryRun(ctx, conn)
if err != nil { return err }
if count == 0 { return fmt.Errorf("nothing to flatten: no commits") }
versioncontrolops.Flatten(ctx, singleConn)
Defensive patterns

Strategy: validation

Validate before calling

count, _, err := versioncontrolops.FlattenDryRun(ctx, conn)
if err != nil { return err }
if count == 0 {
    return fmt.Errorf("cannot flatten: database has no commits")
}

Try / catch

err := versioncontrolops.Flatten(ctx, conn)
if err != nil && strings.Contains(err.Error(), "find initial commit") {
    if errors.Is(err, sql.ErrNoRows) || strings.Contains(err.Error(), "no rows") {
        return fmt.Errorf("empty history: make an initial commit first")
    }
    return err
}

Prevention

When it happens

Trigger: Calling Flatten(ctx, conn) on a freshly initialized database with zero commits in dolt_log; a broken/pooled connection (Flatten requires a single session-scoped connection); context cancellation; dolt_log unreadable.

Common situations: Running flatten before the first commit was ever made in a new beads/Dolt database; passing a pooled *sql.DB instead of a single connection so Dolt stored-procedure session state breaks; server outage.

Related errors


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