gastownhall/beads · error

selecting database %q: %w

Error message

selecting database %q: %w

What it means

This error is raised when the injected DatabaseSelector callback fails to move the pinned session onto the target database (typically by issuing a quoted USE statement). It wraps the selector's own error with the database name for context. It only fires when the session was not already on the target and the database provably exists.

Source

Thrown at internal/storage/schema/converged.go:151

	}
	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
	}

	quoted, err := selector(ctx, db, databaseName)
	if err != nil {
		return false, "", fmt.Errorf("selecting database %q: %w", databaseName, err)
	}
	if quoted == "" {
		return false, "", fmt.Errorf("selecting database %q: selector returned no quoted name", databaseName)
	}
	return true, quoted, nil
}

// migrationLockFree reports whether the database-scoped migration lock is
// currently unheld. IS_FREE_LOCK is a read: it never queues, never acquires,
// and costs one round trip, which is the entire point — the fast path exists
// to stop paying GET_LOCK's queue.
//
// A NULL answer means the server would not tell us, which is not the same as
// "free": fail closed.
func migrationLockFree(ctx context.Context, db DBConn, lockName string) (bool, error) {
	var free sql.NullInt64
	if err := db.QueryRowContext(ctx, "SELECT IS_FREE_LOCK(?)", lockName).Scan(&free); err != nil {
		return false, fmt.Errorf("probing migration lock %q: %w", lockName, err)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run the operation again — the open path is idempotent and the race window is tiny
  2. Check GRANTs: the connecting user must have usage/access on the target database
  3. Verify the database wasn't concurrently dropped (check server logs or SHOW DATABASES)
  4. Inspect the wrapped %w error for connection-level causes and reconnect
Defensive patterns

Strategy: retry

Validate before calling

// confirm the connecting user can select the target database
rows, _ := db.Query("SHOW GRANTS")
// verify output includes USAGE/privileges on `dbname`

Try / catch

if err != nil && strings.Contains(err.Error(), "selecting database") {
    // check grants / database existence, then retry once
}

Prevention

When it happens

Trigger: The selector function (e.g. one issuing USE `dbname`) returns an error — USE fails due to lost connection, insufficient privileges, the database being dropped between the existence probe and the USE, or the context being cancelled.

Common situations: Race where another process drops the database between probe and USE; Dolt sql-server grants revoked; server restart mid-open; stale pooled connection dies on first real statement (the USE).

Related errors


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