gastownhall/beads · warning
uow: bootstrap preparation: %w
Error message
uow: bootstrap preparation: %w
What it means
classifyInitSchemaError wraps an error from schema migration as 'uow: bootstrap preparation' when the error is a bootstrapPreparationError flagged retryable. It marks a database bootstrap/prepare step (CREATE DATABASE, USE, pre-migration prep under the migration lock) that failed transiently and will be retried by the backoff loop. The wrapping keeps the preparation context on the error while letting backoff.Retry continue.
Source
Thrown at internal/storage/uow/dolt_sql_provider.go:82
type bootstrapPreparationError struct {
err error
retryable bool
}
func (e *bootstrapPreparationError) Error() string {
return e.err.Error()
}
func (e *bootstrapPreparationError) Unwrap() error {
return e.err
}
func classifyInitSchemaError(err error) error {
var preparationErr *bootstrapPreparationError
if errors.As(err, &preparationErr) {
if preparationErr.retryable {
return fmt.Errorf("uow: bootstrap preparation: %w", err)
}
return backoff.Permanent(err)
}
if isSerializationError(err) || schema.IsMigrationLockError(err) {
return fmt.Errorf("uow: migrate: %w", err)
}
return backoff.Permanent(fmt.Errorf("uow: migrate: %w", err))
}
// ProviderOption tunes how a SQL-server unit-of-work provider opens. Options
// are variadic so the existing constructor call sites — every one of which
// wants the ordinary mutating open — stay unchanged.
type ProviderOption func(*providerOptions)
type providerOptions struct {
// preview opens for a command that promised not to mutate anything
// (--dry-run, --inspect). Such a command must reach its own RunE before
// anything writes, so the open may neither CREATE DATABASE nor runView on GitHub (pinned to 71377f2769)
Solutions
- Retry is automatic: the initSchema backoff loop (60s budget) will re-attempt; simply re-run the command if the process exited.
- Check that no other bd process is stuck holding the migration lock on the shared Dolt server.
- Verify Dolt server connectivity and load; transient failures under load are the usual cause.
- If it repeatedly fails, inspect the bootstrapPreparationError's wrapped cause for the underlying SQL error.
Defensive patterns
Strategy: retry
Validate before calling
// ensure server reachable before opening the provider
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("dolt server unreachable, bootstrap will retry: %w", err)
} Type guard
var prepErr *uow.BootstrapPreparationError
if errors.As(err, &prepErr) && prepErr.Retryable { /* transient: safe to retry */ } Try / catch
err := provider.Open(ctx, cfg)
if err != nil {
var prepErr *uow.BootstrapPreparationError
if errors.As(err, &prepErr) {
return retryWithBackoff(ctx, func() error { return provider.Open(ctx, cfg) })
}
return err
} Prevention
- Avoid many concurrent cold starts against one fresh Dolt server.
- Keep the migration-lock holder healthy; watchdog stuck migrations.
- Give initSchema's backoff (60s) room: don't use sub-second contexts.
- Monitor server load; bootstrap retries correlate with load spikes.
When it happens
Trigger: During provider open, schema.MigrateUpWithLock's locked-preparation callback (bootstrapPreparer.prepare) returns a *bootstrapPreparationError with retryable=true; classifyInitSchemaError re-wraps it so the backoff retry in initSchema continues after the transient failure.
Common situations: Concurrent bd processes bootstrapping the same Dolt database at cold start; a peer holding the migration lock; brief connection blips to a loaded shared Dolt SQL server during CREATE DATABASE/USE.
Related errors
- database %q not found on Dolt server at %s:%d
- schema: capture fresh-bootstrap identity: %w
- schema: verify fresh-bootstrap history: %w
- schema: verify fresh-bootstrap history: got %d commits, want
- schema: verify fresh-bootstrap working set: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/fd108d3c76d9dbba.
Report an issue: GitHub.