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(&current); 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

  1. Retry the open or migration — a fresh connection from the pool usually succeeds.
  2. Enable connection health checks or ping before use; keep pool idle lifetime below server wait_timeout.
  3. Increase context timeouts if deadlines are hit during startup.
  4. 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(&current); 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(&current); err != nil {
	if !isRetryableConnErr(err) {
		return false, "", fmt.Errorf("reading current database: %w", err)
	}
	if retryErr := db.QueryRowContext(ctx, "SELECT DATABASE()").Scan(&current); 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

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


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