gastownhall/beads · error
failed to load config: %w
Error message
failed to load config: %w
What it means
ConfigValues (cmd/bd/doctor/fix/config_values.go) wraps errors from configfile.Load(beadsDir) with this message. Load fails when .beads/metadata.json exists but is unreadable or unparseable (bad JSON, permissions, I/O error) — distinct from the missing-file case, which returns nil cfg and the "no metadata.json found" error.
Source
Thrown at cmd/bd/doctor/fix/config_values.go:20
import (
"fmt"
"strings"
"github.com/steveyegge/beads/internal/configfile"
)
// ConfigValues fixes invalid configuration values in metadata.json.
// Currently handles: database field pointing to SQLite name when backend is Dolt.
func ConfigValues(path string) error {
beadsDir, err := resolvedWorkspaceBeadsDir(path)
if err != nil {
return err
}
cfg, err := configfile.Load(beadsDir)
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
if cfg == nil {
return fmt.Errorf("no metadata.json found")
}
fixed := false
// Fix database field: when backend is Dolt, database should be "dolt" not "beads.db"
if cfg.GetBackend() == configfile.BackendDolt {
if strings.HasSuffix(cfg.Database, ".db") || strings.HasSuffix(cfg.Database, ".sqlite") || strings.HasSuffix(cfg.Database, ".sqlite3") {
fmt.Printf(" Updating database: %q → %q (Dolt backend uses directory)\n", cfg.Database, "dolt")
cfg.Database = "dolt"
fixed = true
}
}
if !fixed {
fmt.Println(" → No configuration issues to fix")View on GitHub (pinned to 71377f2769)
Solutions
- Inspect .beads/metadata.json for JSON syntax errors (run it through jq or a JSON linter) and fix or restore it
- Fix file permissions: ensure the current user can read .beads/metadata.json (e.g. chmod 644)
- Follow any .beads/redirect to confirm the target beads dir exists and is readable
- If the file is corrupted and unrecoverable, re-initialize the workspace metadata (bd init) and reapply settings
Example fix
// before (invalid JSON)
{ "backend": "dolt", "database": "dolt", }
// after
{ "backend": "dolt", "database": "dolt" } Defensive patterns
Strategy: try-catch
Validate before calling
data, err := os.ReadFile(filepath.Join(beadsDir, "metadata.json"))
if err != nil { return err }
var probe map[string]any
if err := json.Unmarshal(data, &probe); err != nil {
return fmt.Errorf("metadata.json is not valid JSON: %w", err)
} Type guard
func metadataReadable(beadsDir string) bool {
fi, err := os.Stat(filepath.Join(beadsDir, "metadata.json"))
return err == nil && !fi.IsDir() && fi.Mode().Perm()&0o400 != 0
} Try / catch
cfg, err := configfile.Load(beadsDir)
if err != nil {
return fmt.Errorf("failed to load config: %w", err) // surface JSON/permission detail to user
} Prevention
- Validate metadata.json with a JSON parser after hand edits
- Keep consistent user ownership of .beads across sudo/non-sudo runs
- Write metadata.json atomically (temp file + rename) in tooling
- Back up metadata.json before migrations
When it happens
Trigger: configfile.Load returns a non-nil error: malformed JSON in .beads/metadata.json, file permissions deny read, disk I/O error, or the beadsDir resolution produced a path Load cannot read.
Common situations: A partially written or hand-edited metadata.json with a syntax error; running bd as a different user than the one who created the workspace; a .beads/redirect pointing at a directory that is unreadable or on a failed mount.
Related errors
- failed to load config: %w
- ExternalDoltConfig: must set Socket or (Host, Port)
- server: NewDoltServer: doltBinExec is required
- server: NewDoltServer: rootDir is required
- server: NewDoltServer: configPath is required
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/68c6459bdecf376b.
Report an issue: GitHub.