gastownhall/beads · error
reading current database: %w
Error message
reading current database: %w
What it means
This error wraps a failure to run `SELECT DATABASE()` while determining whether the pooled session is already pinned to the target database (selectTargetDatabase). The check exists because a USE of a not-yet-created database would poison the pooled connection (be-bv7x), so the code probes first; if even the probe fails, the connection or context is unhealthy. Callers (alreadyConverged via MigrateUpWithLock) cannot take the fast path.
Source
Thrown at internal/storage/schema/converged.go:129
// A database that does not exist yet is a fresh bootstrap: report false so the
// caller falls through to the locked path, whose CREATE DATABASE arbitrates
// creation and issues the #5012 fresh-bootstrap heal capability.
//
// Selecting is also what makes skipping a caller's locked bootstrap
// preparation safe: preparation creates the database and USEs it, and both
// have provably happened here — the database existed before we touched it (so
// preparation's bare CREATE DATABASE could only have failed with "database
// exists" and captured no heal authority), and the selector issues the same
// USE preparation would.
//
// The existence probe is not decoration. A Dolt session that issues a FAILING
// statement stays pinned to its pre-statement catalog snapshot, so a USE of a
// not-yet-created database would poison this pooled connection for the rest of
// its life (be-bv7x). Probe with a query that always succeeds, then act.
func selectTargetDatabase(ctx context.Context, db DBConn, databaseName string, selector DatabaseSelector) (bool, string, error) {
var current sql.NullString
if err := db.QueryRowContext(ctx, "SELECT DATABASE()").Scan(¤t); err != nil {
return false, "", fmt.Errorf("reading current database: %w", err)
}
if current.Valid && current.String == databaseName {
return true, "", nil
}
if selector == nil {
return false, "", nil
}
var exists int
if err := db.QueryRowContext(ctx,
"SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = ?",
databaseName,
).Scan(&exists); err != nil {
return false, "", fmt.Errorf("probing database %q existence: %w", databaseName, err)
}
if exists == 0 {
return false, "", nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Retry the open or migration — a fresh connection from the pool usually succeeds.
- Enable connection health checks or ping before use; keep pool idle lifetime below server wait_timeout.
- Increase context timeouts if deadlines are hit during startup.
- Check Dolt server logs and connectivity (host, port, TLS) if failures repeat.
Example fix
// before: probe failure aborts
if err := db.QueryRowContext(ctx, "SELECT DATABASE()").Scan(¤t); err != nil {
return false, "", fmt.Errorf("reading current database: %w", err)
}
// after: retry once for transient pool-connection errors
if err := db.QueryRowContext(ctx, "SELECT DATABASE()").Scan(¤t); err != nil {
if !isRetryableConnErr(err) {
return false, "", fmt.Errorf("reading current database: %w", err)
}
if retryErr := db.QueryRowContext(ctx, "SELECT DATABASE()").Scan(¤t); retryErr != nil {
return false, "", fmt.Errorf("reading current database: %w", retryErr)
}
} Defensive patterns
Strategy: retry
Validate before calling
// Ping the connection before schema probes to evict dead pooled connections
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("database connection unhealthy: %w", err)
} Try / catch
res, err := openDatabase(ctx)
if err != nil && strings.Contains(err.Error(), "reading current database:") {
if isTransient(err) { // net.OpError, context deadline, server gone
res, err = openDatabase(ctx) // fresh pool connection
}
} Prevention
- Set connection MaxIdleTime below the server's wait_timeout so stale connections are reaped
- Ping or health-check pooled connections before first use
- Use adequately generous context timeouts during startup
- Monitor Dolt server availability and restarts
When it happens
Trigger: SELECT DATABASE() returns a driver error: connection closed or dropped, context cancelled or deadline exceeded, server unavailable, or the pooled connection was killed server-side.
Common situations: Dolt server restart between pool creation and first query; idle connection reaped by the server (wait_timeout); context timeout too tight during startup; network partition to a remote Dolt server.
Related errors
- dolt server connection failed: %w
- failed to reach the workspace identity: %v
- begin tx: %w
- begin read tx: %w
- begin write tx: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/427a281047c703b7.
Report an issue: GitHub.