gastownhall/beads · error
selecting database %q: selector returned no quoted name
Error message
selecting database %q: selector returned no quoted name
What it means
A defensive error: after the DatabaseSelector reports success, it must return the identifier-quoted database name used to schema-qualify later reads (e.g. `mydb`.dolt_ignore). An empty string means the selector violated its contract, so selectTargetDatabase cannot safely qualify subsequent unqualified reads and fails loudly instead of silently misreading another database.
Source
Thrown at internal/storage/schema/converged.go:154
}
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)
}
if !free.Valid {
return false, nilView on GitHub (pinned to 71377f2769)
Solutions
- Fix the DatabaseSelector implementation to always return the backtick-quoted database name on success (e.g. fmt.Sprintf("`%s`", name) after validating the name)
- Check the selector's empty-return code path (early returns, helper functions returning "")
- If using the library-provided selectors, report/upgrade — stock selectors always quote
Example fix
// before
func mySelector(ctx context.Context, db DBConn, name string) (string, error) {
if _, err := db.ExecContext(ctx, "USE "+name); err != nil { return "", err }
return "", nil // BUG: forgot to return quoted name
}
// after
func mySelector(ctx context.Context, db DBConn, name string) (string, error) {
quoted := "`" + name + "`"
if _, err := db.ExecContext(ctx, "USE "+quoted); err != nil { return "", err }
return quoted, nil
} Defensive patterns
Strategy: validation
Validate before calling
// validate a custom selector's contract before installing it
quoted, err := sel(ctx, db, "testdb")
if err != nil || quoted == "" {
return fmt.Errorf("selector must return non-empty quoted name")
} Type guard
func validSelector(sel DatabaseSelector) bool {
return sel != nil
}
// and assert its output: quoted != "" before proceeding Prevention
- Custom DatabaseSelector implementations must always return the backtick-quoted name on success
- Unit-test any custom selector against the empty-string case
- Prefer library-provided selectors
When it happens
Trigger: A custom DatabaseSelector implementation returns ("", nil) — i.e. it claims success but does not return the quoted identifier. Only possible when the caller supplies a non-nil selector and the session was not already on the target database.
Common situations: A selector implementation that issues USE but forgets to build/return the quoted name; a selector returning the result of a helper that itself returns empty on some code path; writing a new selector for an embedded driver and mishandling the success branch.
Related errors
- dolt directory is required
- dolt binary not found
- dolt path is not executable
- dolt version probe failed
- dolt version output is unparseable
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f746e573bfca8635.
Report an issue: GitHub.