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

  1. Inspect .beads/metadata.json for JSON syntax errors (run it through jq or a JSON linter) and fix or restore it
  2. Fix file permissions: ensure the current user can read .beads/metadata.json (e.g. chmod 644)
  3. Follow any .beads/redirect to confirm the target beads dir exists and is readable
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/68c6459bdecf376b. Report an issue: GitHub.