gastownhall/beads · error

schema: capture fresh-bootstrap identity: %w

Error message

schema: capture fresh-bootstrap identity: %w

What it means

CaptureFreshBootstrapHealCapability failed while running its identity probe `SELECT DATABASE(), @@server_uuid, DOLT_HASHOF('HEAD')` on the pinned connection, right after a bare CREATE DATABASE. The library wraps the underlying SQL driver error so the caller knows bootstrap-identity capture, not migration itself, failed. Because capture authority is issued fail-closed, any probe error means no fresh-bootstrap heal capability is produced.

Source

Thrown at internal/storage/schema/lock.go:117

// set. Any uncertainty fails closed instead of issuing reset authority.
func CaptureFreshBootstrapHealCapability(
	ctx context.Context,
	conn *sql.Conn,
	endpoint string,
	expectedDatabase string,
) (*FreshBootstrapHealCapability, error) {
	if endpoint == "" {
		return nil, errors.New("schema: capture fresh-bootstrap identity: empty endpoint")
	}
	if expectedDatabase == "" {
		return nil, errors.New("schema: capture fresh-bootstrap identity: empty database name")
	}

	var databaseName, serverUUID, initialHead string
	if err := conn.QueryRowContext(ctx,
		"SELECT DATABASE(), @@server_uuid, DOLT_HASHOF('HEAD')",
	).Scan(&databaseName, &serverUUID, &initialHead); err != nil {
		return nil, fmt.Errorf("schema: capture fresh-bootstrap identity: %w", err)
	}
	if databaseName != expectedDatabase {
		return nil, fmt.Errorf("schema: capture fresh-bootstrap identity: database is %q, want %q", databaseName, expectedDatabase)
	}
	if serverUUID == "" {
		return nil, errors.New("schema: capture fresh-bootstrap identity: empty server UUID")
	}
	if initialHead == "" {
		return nil, errors.New("schema: capture fresh-bootstrap identity: empty initial HEAD")
	}

	var commitCount, dirtyCount int
	if err := conn.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_log").Scan(&commitCount); err != nil {
		return nil, fmt.Errorf("schema: verify fresh-bootstrap history: %w", err)
	}
	if commitCount != 1 {
		return nil, fmt.Errorf("schema: verify fresh-bootstrap history: got %d commits, want 1", commitCount)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped cause (%w) to identify the actual driver error; fix that first (e.g. reconnect, correct server).
  2. Verify you are connecting to a Dolt sql-server that supports DOLT_HASHOF and @@server_uuid.
  3. Ensure the session has a database selected or the DSN names the database before capture.
  4. Retry the whole open/bootstrap; the capability is designed to fail closed and the caller's retry loop should re-run CREATE DATABASE + capture.

Example fix

// before
conn, _ := pool.Conn(ctx)
cap, err := schema.CaptureFreshBootstrapHealCapability(ctx, conn, endpoint, dbName) // fails: server lacks DOLT_HASHOF
// after
// point endpoint at the Dolt sql-server, and pass a bounded ctx
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
cap, err := schema.CaptureFreshBootstrapHealCapability(ctx, conn, doltEndpoint, dbName)
Defensive patterns

Strategy: retry

Validate before calling

if endpoint == "" || dbName == "" { return errors.New("endpoint and database name are required") }
if err := conn.PingContext(ctx); err != nil { return fmt.Errorf("connection not usable: %w", err) }

Type guard

func isCaptureProbeFailure(err error) bool {
	return err != nil && strings.Contains(err.Error(), "capture fresh-bootstrap identity:") && !strings.Contains(err.Error(), "want")
}

Try / catch

cap, err := schema.CaptureFreshBootstrapHealCapability(ctx, conn, endpoint, db)
if err != nil {
	if ctx.Err() != nil { return ctx.Err() }
	// fail closed: no heal authority; retry whole open/bootstrap
	return fmt.Errorf("bootstrap capture failed: %w", err)
}

Prevention

When it happens

Trigger: Calling CaptureFreshBootstrapHealCapability when the connection is broken, the session has no database selected (DATABASE() is fine but @@server_uuid/DOLT_HASHOF fail), the server is not Dolt-aware (DOLT_HASHOF unknown), or the context is cancelled/times out mid-query.

Common situations: Connecting to a non-Dolt MySQL server that lacks DOLT_HASHOF; a pooled connection dropped by an idle timeout; a Dolt sql-server restarting during init; a ctx deadline expiring because the server is slow to accept the new database.

Related errors


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