gastownhall/beads · error
schema: read database name: %w
Error message
schema: read database name: %w
What it means
After pinning a connection, the schema initializer runs SELECT DATABASE() to learn which database the connection is scoped to; this error wraps a failure to scan that result. It means the pinned connection exists but the trivial query failed or returned no row (NULL database, e.g. no default schema selected).
Source
Thrown at internal/storage/dolt/store.go:2601
}
// initSchemaOnDBWithBootstrapHeal threads one-shot, incarnation-bound reset
// authority into the migration lock. A nil capability always fails closed.
func initSchemaOnDBWithBootstrapHeal(
ctx context.Context,
db *sql.DB,
bootstrapHeal *schema.FreshBootstrapHealCapability,
endpoint string,
) (int, error) {
conn, err := db.Conn(ctx)
if err != nil {
return 0, fmt.Errorf("schema: pin connection: %w", err)
}
defer conn.Close()
var dbName string
if err := conn.QueryRowContext(ctx, "SELECT DATABASE()").Scan(&dbName); err != nil {
return 0, fmt.Errorf("schema: read database name: %w", err)
}
var opts []schema.MigrateLockOption
if bootstrapHeal != nil {
opts = append(opts, schema.WithFreshBootstrapHeal(bootstrapHeal, endpoint))
}
applied, err := schema.MigrateUpWithLock(ctx, conn, dbName, opts...)
if err != nil {
return applied, fmt.Errorf("schema migration: %w", err)
}
return applied, nil
}
func initSchemaOnDBWithRetry(ctx context.Context, db *sql.DB) (int, error) {
return initSchemaOnDBWithRetryAndGate(ctx, db, nil)
}
// initSchemaOnDBWithRetryAndGate is initSchemaOnDBWithRetry with an optionalView on GitHub (pinned to 71377f2769)
Solutions
- Include the database name in the DSN so DATABASE() is non-NULL
- Inspect the wrapped error: nil-row Scan (sql.ErrNoRows) means no default DB selected; driver errors mean check server health
- Retry after reconnecting; a stale pinned connection is re-pinned on the next call
- Verify ctx deadline is generous enough for pool pin + query
Example fix
// before dsn := "user:pass@tcp(localhost:3306)/" // after dsn := "user:pass@tcp(localhost:3306)/mydb"
Defensive patterns
Strategy: validation
Validate before calling
// ensure DSN names a database so SELECT DATABASE() is non-NULL
cfg, err := mysql.ParseDSN(connStr)
if err != nil || cfg.DBName == "" {
return fmt.Errorf("DSN must include a database name")
} Try / catch
// Go: distinguish no-default-DB from driver failure
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
// DATABASE() NULL: DSN missing dbname
}
return fmt.Errorf("schema: read database name: %w", err)
} Prevention
- Always include the database name in the DSN
- Keep migration contexts timeout-bounded but generous
- Re-create pools after server restarts instead of reusing stale ones
When it happens
Trigger: initSchemaOnDBWithRetryAndGate executing conn.QueryRowContext(ctx, "SELECT DATABASE()").Scan(&dbName) when: the query errors (connection dropped, server gone, ctx canceled), or Scan fails because DATABASE() is NULL (connection without a database selected in the DSN).
Common situations: DSN missing the database name (e.g. 'user:pass@tcp(host:port)/' with empty dbname), Dolt server restarted between pin and query, context deadline exceeded, credentials revoked mid-session.
Related errors
- schema migration: %w
- schema: pin connection: %w
- failed to open migration connection: %w
- failed to insert initial issue counter for prefix %q: %w
- failed to check existing counter for prefix %q: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5797474cd41ef171.
Report an issue: GitHub.