gastownhall/beads · error

count commits: %w

Error message

count commits: %w

What it means

Flatten counts commits in dolt_log to decide whether flattening is needed. If the SELECT COUNT(*) query or Scan fails — connection error, context cancellation, database unavailability — the error is wrapped as "count commits: %w" and Flatten aborts before making any changes.

Source

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

// 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
	}

	steps := []struct {
		name  string
		query string
		args  []interface{}
	}{
		{"create temp branch", "CALL DOLT_BRANCH('flatten-tmp')", nil},

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped error and verify the connection is healthy (db.PingContext), then retry.
  2. Confirm the target is a Dolt database exposing dolt_log.
  3. Use a single dedicated connection for the whole Flatten call, as required by its doc.
  4. Prefer FlattenDryRun for read-only checks so failures never risk partial flatten steps.

Example fix

// before
versioncontrolops.Flatten(ctx, pooledDB)
// after
if err := conn.PingContext(ctx); err != nil { return err }
if _, _, err := versioncontrolops.FlattenDryRun(ctx, conn); err != nil {
    return fmt.Errorf("dolt unreachable: %w", err)
}
versioncontrolops.Flatten(ctx, conn)
Defensive patterns

Strategy: try-catch

Validate before calling

if err := conn.PingContext(ctx); err != nil {
    return fmt.Errorf("dolt connection unhealthy: %w", err)
}

Try / catch

err := versioncontrolops.Flatten(ctx, conn)
if err != nil && strings.Contains(err.Error(), "count commits") {
    if errors.Is(err, context.DeadlineExceeded) {
        return fmt.Errorf("flatten aborted before changes; increase timeout and retry")
    }
    return err
}

Prevention

When it happens

Trigger: Calling Flatten(ctx, conn) when the Dolt connection is down or dropped between queries; context deadline exceeded; the database is not a valid Dolt database so dolt_log does not exist.

Common situations: Server restart between the initial-commit lookup and the count query; connecting to a non-Dolt schema; network timeout on a remote sql-server; using a pooled connection whose session died.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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