gastownhall/beads · error
db: SetLocalMetadata %s: %w
Error message
db: SetLocalMetadata %s: %w
What it means
This error wraps the underlying SQL driver failure from an INSERT/REPLACE into the local_metadata table in the Dolt-backed storage layer. SetLocalMetadata writes a key/value row used for repo-local metadata; when the ExecContext call fails, the error is wrapped as "db: SetLocalMetadata <key>: <cause>" so callers know which metadata key could not be persisted. The root cause is always in the wrapped driver error (connection loss, schema problem, constraint, etc.).
Source
Thrown at internal/storage/domain/db/config.go:61
}
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 {
return "", fmt.Errorf("db: GetLocalMetadata %s: %w", key, err)
}
return value, nil
}
func (r *configSQLRepositoryImpl) SetLocalMetadata(ctx context.Context, key, value string) error {
if _, err := r.runner.ExecContext(ctx, "REPLACE INTO local_metadata (`key`, value) VALUES (?, ?)", key, value); err != nil {
return fmt.Errorf("db: SetLocalMetadata %s: %w", key, err)
}
return nil
}
func (r *configSQLRepositoryImpl) GetConfig(ctx context.Context, key string) (string, error) {
var value string
err := r.runner.QueryRowContext(ctx, "SELECT value FROM config WHERE `key` = ?", key).Scan(&value)
if errors.Is(err, sql.ErrNoRows) {
return "", nil
}
if err != nil {
return "", fmt.Errorf("db: GetConfig %s: %w", key, err)
}
return value, nil
}
func (r *configSQLRepositoryImpl) SetConfig(ctx context.Context, key, value string) error {
if key == "issue_prefix" {View on GitHub (pinned to 71377f2769)
Solutions
- Run the driver's schema/migration path (e.g. `bd doctor` or re-open the repo) to ensure the local_metadata table exists
- Inspect the wrapped cause (the %w chain) to identify whether it is I/O, locking, or schema related and fix accordingly
- Check disk space and file permissions on the database directory
- Ensure no other process holds a conflicting lock on the Dolt database, then retry
- If the database is corrupt, restore from backup or re-init the repo
Example fix
// before
if _, err := db.Exec("REPLACE INTO local_metadata (`key`, value) VALUES (?, ?)", k, v); err != nil {
return fmt.Errorf("set failed")
}
// after
if _, err := db.Exec("REPLACE INTO local_metadata (`key`, value) VALUES (?, ?)", k, v); err != nil {
return fmt.Errorf("db: SetLocalMetadata %s: %w", k, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if err := doctor.CheckSchema(ctx, repo); err != nil {
return fmt.Errorf("schema not ready for local_metadata: %w", err)
} Try / catch
if err := repo.SetLocalMetadata(ctx, key, value); err != nil {
var drv *driver.Error
if errors.As(err, &drv) {
// inspect drv for lock/IO/table cause before retrying
}
return fmt.Errorf("persisting %q failed: %w", key, err)
} Prevention
- Run `bd doctor` after upgrading bd so new metadata tables are created before use
- Avoid concurrent bd processes on the same repo or use locking
- Monitor disk space where the .beads database lives
- Always inspect the wrapped (%w) cause rather than treating all failures alike
When it happens
Trigger: Calling SetLocalMetadata(ctx, key, value) when the REPLACE INTO local_metadata statement fails: database file corrupted or locked, local_metadata table missing (schema migration not run), connection dropped mid-write, or a driver-level constraint/IO error.
Common situations: Running bd commands against a .beads database whose schema predates the local_metadata table; disk full or database file corrupted after a crash; concurrent access locking the Dolt database; version mismatch where an older binary opens a newer schema.
Related errors
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5627ed29463c04d8.
Report an issue: GitHub.