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 = actualDB

View on GitHub (pinned to 71377f2769)

Solutions

  1. Validate .beads/metadata.json JSON syntax (jq . .beads/metadata.json) and repair or restore it
  2. Fix read permissions on .beads/metadata.json and the .beads directory
  3. Resolve the .beads/redirect target and confirm it exists and is readable
  4. 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

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


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