gastownhall/beads · error
failed to load config: %w
Error message
failed to load config: %w
What it means
DatabaseConfig (cmd/bd/doctor/fix/database_config.go) wraps errors from configfile.Load(beadsDir) with this message. Load fails when .beads/metadata.json exists but cannot be read or parsed (malformed JSON, permission denied, I/O error), as opposed to the missing-file case which yields the "no metadata.json found" error.
Source
Thrown at cmd/bd/doctor/fix/database_config.go:24
"strings"
"github.com/steveyegge/beads/internal/configfile"
)
// DatabaseConfig auto-detects and fixes metadata.json database config mismatches.
// This fix only applies to SQLite backends where .db files on disk may not match
// the configured database name. Dolt backends store data on a server, so there
// are no local .db files to reconcile.
func DatabaseConfig(path string) error {
beadsDir, err := resolvedWorkspaceBeadsDir(path)
if err != nil {
return err
}
// Load existing config
cfg, err := configfile.Load(beadsDir)
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
if cfg == nil {
// No config exists - nothing to fix
return fmt.Errorf("no metadata.json found")
}
// Dolt backend stores data on the server — no local .db files to reconcile
if cfg.GetBackend() == configfile.BackendDolt {
return fmt.Errorf("database config fix not applicable for Dolt backend (data is on the server)")
}
fixed := false
// Check if configured database name matches the actual .db file on disk
actualDB := findActualDBFile(beadsDir)
if actualDB != "" && cfg.Database != actualDB {
fmt.Printf(" Updating database: %s → %s\n", cfg.Database, actualDB)
cfg.Database = actualDBView on GitHub (pinned to 71377f2769)
Solutions
- Validate .beads/metadata.json JSON syntax (jq . .beads/metadata.json) and repair or restore it
- Fix read permissions on .beads/metadata.json and the .beads directory
- Resolve the .beads/redirect target and confirm it exists and is readable
- Re-run `bd init` to regenerate metadata if the file is unrecoverable, then reapply backend/database settings
Example fix
// before (truncated)
{ "backend": "sqlite", "data
// after
{ "backend": "sqlite", "database": "beads.db" } 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
if err := fix.DatabaseConfig(path); err != nil {
if strings.HasPrefix(err.Error(), "failed to load config") {
// inspect metadata.json JSON validity and permissions
}
return err
} Prevention
- Lint metadata.json after manual edits
- Keep .beads ownership consistent across users
- Resolve redirect targets before running database fixes
- Regenerate metadata via `bd init` if it is corrupted
When it happens
Trigger: configfile.Load returns a non-nil error during DatabaseConfig: invalid JSON in .beads/metadata.json, unreadable file permissions, or an unreadable resolved beads dir (possibly via .beads/redirect).
Common situations: Hand-edited or truncated metadata.json; running bd as a different user; redirect target on a failed/unmounted drive; corrupted metadata after an interrupted write.
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/79eef905ac2b741c.
Report an issue: GitHub.