gastownhall/beads · error
rebuild pool after migration: %w
Error message
rebuild pool after migration: %w
What it means
After a migration applied changes, rebuildPoolAfterMigration opens a fresh connection pool with sql.Open using the store's connection string; this error wraps that open failing. As with sql.Open generally, it usually means driver/DSN-level problems rather than server availability (ping failures produce the sibling error at line 2777).
Source
Thrown at internal/storage/dolt/store.go:2771
}
// rebuildPoolAfterMigration replaces the main connection pool (s.db) after a
// migrating open. Migrations run over a separate one-off pool
// (openMigrationDB); a connection already pooled in s.db before migrations
// ran (e.g. the startup Ping in newServerMode) stays pinned to the
// pre-migration Dolt session root, so the first read through it returns 0
// rows / table-not-found and does not self-heal on retry (be-itm5). A
// non-migrating open (applied == 0 — the common re-open-of-an-
// already-migrated-database path) has no stale state to fix and must return
// before touching s.db or dialing anything.
func (s *DoltStore) rebuildPoolAfterMigration(ctx context.Context, applied int) error {
if applied == 0 {
return nil
}
newDB, err := sql.Open("mysql", s.connStr)
if err != nil {
return fmt.Errorf("rebuild pool after migration: %w", err)
}
applyPoolLimits(newDB, s.cfg)
if err := newDB.PingContext(ctx); err != nil {
_ = newDB.Close()
return fmt.Errorf("rebuild pool after migration: %w", err)
}
old := s.db
s.db = newDB
return old.Close()
}
// IsClosed returns true if the store has been closed.
func (s *DoltStore) IsClosed() bool {
return s.closed.Load()
}
View on GitHub (pinned to 71377f2769)
Solutions
- Validate s.connStr is a well-formed DSN before constructing the store (mysql.ParseDSN in a startup check)
- Ensure the mysql driver import is present in the binary
- If seen in tests, construct DoltStore with a real ParseDSN-validated connection string
Example fix
// before
if _, err := sql.Open("mysql", s.connStr); err != nil { ... }
// after
if _, err := mysql.ParseDSN(s.connStr); err != nil {
return fmt.Errorf("invalid connStr: %w", err)
}
newDB, err := sql.Open("mysql", s.connStr) Defensive patterns
Strategy: validation
Validate before calling
// validate connStr before pool rebuild
if _, err := mysql.ParseDSN(s.connStr); err != nil {
return fmt.Errorf("cannot rebuild pool, bad connStr: %w", err)
} Try / catch
// Go: driver-registration failures are permanent; surface at startup
newDB, err := sql.Open("mysql", s.connStr)
if err != nil {
// do not retry: missing driver / invalid DSN is a build/config bug
return fmt.Errorf("rebuild pool after migration: %w", err)
} Prevention
- Parse the DSN once at store construction and reuse the parsed cfg
- Keep the mysql driver import in the main binary
- Use a real DSN (never empty string) in test store construction
When it happens
Trigger: rebuildPoolAfterMigration invoked with applied>0 migrations, and sql.Open("mysql", s.connStr) errors because the mysql driver is not registered or s.connStr is invalid in a way that survives sql.Open validation (empty string, corrupt).
Common situations: connStr mutated to empty/invalid during runtime reconfiguration; driver not linked into binary; tests constructing DoltStore by hand with a bogus connStr then triggering a migration path.
Related errors
- schema: pin connection: %w
- failed to parse DSN for migration connection: %w
- dolt directory is required
- invalid database name: %q; hyphens are not allowed in embedd
- embeddeddolt: invalid database name: %q; hyphens are not all
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/8aa8aca18cc11d71.
Report an issue: GitHub.