gastownhall/beads · warning

schema: verify fresh-bootstrap working set: got %d dirty ent

Error message

schema: verify fresh-bootstrap working set: got %d dirty entries, want 0

What it means

A freshly created database must have zero dirty entries in dolt_status. Non-zero means uncommitted working-set changes exist (e.g. tables created outside Dolt versioning or a previous crashed bootstrap), so the library withholds DOLT_RESET authority rather than discarding unknown work.

Source

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

	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)
	}
	if err := conn.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_status").Scan(&dirtyCount); err != nil {
		return nil, fmt.Errorf("schema: verify fresh-bootstrap working set: %w", err)
	}
	if dirtyCount != 0 {
		return nil, fmt.Errorf("schema: verify fresh-bootstrap working set: got %d dirty entries, want 0", dirtyCount)
	}

	return &FreshBootstrapHealCapability{
		endpoint:     endpoint,
		serverUUID:   serverUUID,
		databaseName: databaseName,
		initialHead:  initialHead,
	}, nil
}

// WithFreshBootstrapHeal enables the fresh-bootstrap self-heal for the #4566
// dirty-table guard (gastownhall/beads#5012). The capability must have been
// captured immediately after this logical open's exact CREATE DATABASE, and
// endpoint must identify the connection pool used for migration. Before any
// DOLT_RESET, MigrateUpWithLock revalidates the capability against the pinned,
// locked session and consumes it atomically.
func WithFreshBootstrapHeal(capability *FreshBootstrapHealCapability, endpoint string) MigrateLockOption {
	return func(o *migrateLockOptions) {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Ensure no other process can write between CREATE DATABASE and capture (hold the migration lock / single initializer).
  2. If a previous crashed bootstrap left dirty tables, let MigrateUpWithLock's fresh-bootstrap heal path handle it instead of capture.
  3. Run `CALL DOLT_RESET('--hard')` manually only if you have verified the working set is disposable.
  4. Re-create the database cleanly if its contents are disposable.

Example fix

// before
_, _ = conn.ExecContext(ctx, "CREATE DATABASE `x`")
// ...other code writes tables...
cap, _ := schema.CaptureFreshBootstrapHealCapability(ctx, conn, endpoint, "x") // dirty
// after
_, _ = conn.ExecContext(ctx, "CREATE DATABASE `x`")
cap, err := schema.CaptureFreshBootstrapHealCapability(ctx, conn, endpoint, "x") // capture immediately, before any DDL
Defensive patterns

Strategy: validation

Validate before calling

var dirty int
if err := conn.QueryRowContext(ctx, "SELECT COUNT(*) FROM dolt_status").Scan(&dirty); err != nil { return err }
if dirty != 0 { return fmt.Errorf("working set dirty (%d); capture skipped", dirty) }

Try / catch

cap, err := schema.CaptureFreshBootstrapHealCapability(ctx, conn, endpoint, db)
if err != nil && strings.Contains(err.Error(), "dirty entries") {
    // do NOT reset blindly; let MigrateUpWithLock's guarded heal path decide
}

Prevention

When it happens

Trigger: Capture runs after something wrote to the database post-CREATE DATABASE (another process migrated first, DDL ran outside a commit, or an earlier interrupted bootstrap left tables behind).

Common situations: Concurrent bd/server instances initializing the same new database; a prior crashed init leaving dirty tables — the exact case the later heal path is meant to handle, but only via the locked, validated path.

Related errors


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