gastownhall/beads · error
db: GetMetadata %s: %w
Error message
db: GetMetadata %s: %w
What it means
GetMetadata reads a single row from the shared metadata table by key. A missing key is not an error (it returns "", nil), so this wrapper only fires when the SELECT itself fails: database unavailable, metadata table missing (uninitialized/pre-migration schema), permission denied, or context cancellation. The failing key is embedded in the message for diagnosis.
Source
Thrown at internal/storage/domain/db/config.go:35
func NewConfigSQLRepository(runner Runner) domain.ConfigSQLRepository {
return &configSQLRepositoryImpl{runner: runner}
}
type configSQLRepositoryImpl struct {
runner Runner
}
var _ domain.ConfigSQLRepository = (*configSQLRepositoryImpl)(nil)
func (r *configSQLRepositoryImpl) GetMetadata(ctx context.Context, key string) (string, error) {
var value string
err := r.runner.QueryRowContext(ctx, "SELECT value FROM metadata WHERE `key` = ?", key).Scan(&value)
if errors.Is(err, sql.ErrNoRows) {
return "", nil
}
if err != nil {
return "", fmt.Errorf("db: GetMetadata %s: %w", key, err)
}
return value, nil
}
func (r *configSQLRepositoryImpl) SetMetadata(ctx context.Context, key, value string) error {
if _, err := r.runner.ExecContext(ctx, "REPLACE INTO metadata (`key`, value) VALUES (?, ?)", key, value); err != nil {
return fmt.Errorf("db: SetMetadata %s: %w", key, err)
}
return nil
}
func (r *configSQLRepositoryImpl) GetLocalMetadata(ctx context.Context, key string) (string, error) {
var value string
err := r.runner.QueryRowContext(ctx, "SELECT value FROM local_metadata WHERE `key` = ?", key).Scan(&value)
if errors.Is(err, sql.ErrNoRows) {
return "", nil
}
if err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause (%w) for the concrete driver error.
- Run bd doctor / migrations to ensure the metadata table exists in the target database.
- Check database connectivity, file permissions, and that the DB isn't locked by another process.
- Retry transient failures; treat empty-string (not error) as the signal for a missing key.
Example fix
// before
v, err := configRepo.GetMetadata(ctx, "issue_prefix") // fails on legacy DB
// after
if err := migrate.EnsureSchema(db); err != nil {
return err
}
v, err := configRepo.GetMetadata(ctx, "issue_prefix") Defensive patterns
Strategy: fallback
Validate before calling
// verify DB reachability and schema before depending on metadata
if err := runner.PingContext(ctx); err != nil {
return fmt.Errorf("database unavailable: %w", err)
} Type guard
null
Try / catch
v, err := configRepo.GetMetadata(ctx, key)
if err != nil {
if strings.Contains(err.Error(), "no such table") {
// run bd doctor / migrations to create the metadata table
}
return fmt.Errorf("metadata read failed for %s: %w", key, err)
}
if v == "" {
// key absent: use default — this is NOT an error
} Prevention
- Remember missing keys return ("", nil); only real SQL failures return this error.
- Keep schema migrated so the metadata table exists.
- Treat empty string as the default-value signal instead of error-based checks.
- Retry transient failures with backoff.
When it happens
Trigger: QueryRowContext("SELECT value FROM metadata WHERE `key` = ?").Scan returns an error other than sql.ErrNoRows — e.g. corrupt/locked Dolt or SQLite file, metadata table absent in a fresh or legacy database, or the connection dropped mid-query.
Common situations: Running bd against a database created by an older version without the metadata table; read-only filesystem/permissions; network blip to a remote Dolt server; database locked by another writer.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- db: CommentSQLRepository.InsertRecord: check issue existence
- db: SetMetadata %s: %w
- db: GetLocalMetadata %s: %w
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4fc9032dcf4be653.
Report an issue: GitHub.