gastownhall/beads · error

schema: fresh-bootstrap reset: %w

Error message

schema: fresh-bootstrap reset: %w

What it means

During the fresh-bootstrap self-heal, after the dirty-tables guard fired, the library runs `CALL DOLT_RESET('--hard')` (drained on the pinned session). If that reset fails, the original DirtyTablesError is joined with this reset error and returned. This is a destructive recovery step failing, so migrations could not be re-run from a clean slate.

Source

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

		// database-scoped migration lock is still held. A mismatch, missing
		// ancestor, probe error, or previously consumed capability returns the
		// original DirtyTablesError without attempting a destructive reset.
		if !o.freshBootstrapHeal.capability.consumeIfCurrentIncarnation(
			ctx, conn, databaseName, o.freshBootstrapHeal.endpoint,
		) {
			return applied, err
		}

		// Consume occurs before the reset call. Thus a reset error or a
		// transient failure in the following migration pass cannot re-arm a
		// second reset in the caller's outer retry loop.
		fmt.Fprintf(stderr, "Discarding interrupted-bootstrap working set (%s) and re-running migrations…\n",
			strings.Join(dirtyErr.Tables, ", "))
		// Drained, not Exec'd: the very next thing this path does is re-run the
		// whole MigrateUp pass on this same pinned connection, so an
		// undrained proc result set here would poison every statement of it.
		if resetErr := DrainCall(ctx, conn, "CALL DOLT_RESET('--hard')"); resetErr != nil {
			return applied, errors.Join(err, fmt.Errorf("schema: fresh-bootstrap reset: %w", resetErr))
		}
		applied, err = MigrateUp(ctx, conn)
	}
	return applied, err
}

// consumeIfCurrentIncarnation validates and atomically consumes c. All probes
// run on the same pinned session while MigrateUpWithLock holds the migration
// lock. Query errors deliberately collapse to false so callers preserve and
// return the original DirtyTablesError.
func (c *FreshBootstrapHealCapability) consumeIfCurrentIncarnation(
	ctx context.Context,
	conn *sql.Conn,
	databaseName string,
	endpoint string,
) bool {
	if c == nil || c.consumed.Load() {
		return false

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect both joined errors; fix the reset cause (connectivity, server health) before retrying.
  2. Retry the open: the capability is consumed, so a retry takes the normal path; manually run DOLT_RESET('--hard') if you've confirmed the working set is disposable.
  3. Check server logs for why DOLT_RESET failed (read-only filesystem, lock conflicts).
  4. As a last resort drop and recreate the database if it's genuinely fresh/disposable.

Example fix

// before
// capability consumed, reset failed; blind outer retry does nothing
// after
// verify and reset manually once server is healthy:
// CALL DOLT_RESET('--hard');
applied, err := schema.MigrateUpWithLock(ctx, conn, dbName)
Defensive patterns

Strategy: try-catch

Validate before calling

// before opting into heal, confirm reset is acceptable:
// the database must be freshly created this logical open (hold the capability)
if cap == nil { /* heal disabled; dirty tables are fatal */ }

Type guard

var dirtyErr *schema.DirtyTablesError
if errors.As(err, &dirtyErr) && strings.Contains(err.Error(), "fresh-bootstrap reset") {
    // heal reset itself failed
}

Try / catch

applied, err := schema.MigrateUpWithLock(ctx, conn, db, schema.WithFreshBootstrapHeal(cap, endpoint))
if err != nil && strings.Contains(err.Error(), "fresh-bootstrap reset") {
    // capability already consumed; fix server health, then either
    // run CALL DOLT_RESET('--hard') manually or drop/recreate the db
}

Prevention

When it happens

Trigger: MigrateUpWithLock with WithFreshBootstrapHeal where MigrateUp returns DirtyTablesError, the capability validates and is consumed, but DOLT_RESET errors — server error, connection drop, or the proc result cannot be drained.

Common situations: Interrupted bootstrap left dirty tables AND the server is unhealthy (restart, disk full, permissions); a pinned session corrupted by earlier undrained result sets.

Related errors


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