gastownhall/beads · error

load %s: %w; no storage database was opened or modified (sto

Error message

load %s: %w; no storage database was opened or modified (storage mode unknown; data commands refuse to fall back to the embedded store)

What it means

At startup bd must learn whether it should run in server mode by loading config/metadata.json from the .beads directory. If configfile.LoadForDiscovery fails (e.g. corrupt or unreadable metadata.json), bd aborts with this error and explicitly does NOT fall back to the embedded store, because storage mode would be unknown and data commands could write to the wrong backend.

Source

Thrown at cmd/bd/main.go:469

	fmt.Fprintln(os.Stderr, "  To stay embedded: unset BEADS_DOLT_SHARED_SERVER (or remove dolt.shared-server from config.yaml).")
}

// loadServerModeFromBeadsDir loads the storage mode (embedded vs server vs
// proxied-server) from the given beads directory's metadata.json so that
// usesSQLServer() and usesProxiedServer() return the correct values.
//
// A metadata.json that exists but cannot be loaded is a hard error: treating
// it like an absent file silently flips server-mode deployments onto the
// embedded store, where every query answers from an empty relic with exit 0
// (false-empty). Absent metadata.json (cfg == nil) keeps the fresh-repo
// embedded default.
func loadServerModeFromBeadsDir(beadsDir string) error {
	if beadsDir == "" {
		return nil
	}
	cfg, err := configfile.LoadForDiscovery(beadsDir)
	if err != nil {
		return fmt.Errorf("load %s: %w; no storage database was opened or modified (storage mode unknown; data commands refuse to fall back to the embedded store)", configfile.ConfigPath(beadsDir), err)
	}
	// Absent metadata.json keeps the fresh-repo embedded default unless
	// env/config.yaml supply a remote host (GH#3545) — inference must not
	// depend on metadata existing.
	cfg = normalizeLoadedConfig(cfg)
	warnSharedServerEmbeddedMismatch(cfg)
	psm := cfg.IsDoltProxiedServerMode()
	sm := cfg.IsDoltServerMode()
	// GH#2946: shared-server override for stale metadata.json (no-db commands)
	if !sm && !psm && doltserver.IsSharedServerMode() {
		sm = true
	}
	serverMode = sm
	proxiedServerMode = psm
	if cmdCtx != nil {
		cmdCtx.ServerMode = sm
		cmdCtx.ProxiedServerMode = psm
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect and repair config/metadata.json (validate JSON, restore from backup or git history)
  2. Delete the corrupt metadata.json only if you accept fresh-repo embedded defaults (re-infer from env/config.yaml)
  3. Check file permissions on the .beads directory
  4. Run `bd doctor` after repair to confirm storage mode resolves correctly

Example fix

// before
$ cat .beads/config/metadata.json
{"server_remote": "https://...",,}   # trailing comma, invalid JSON
// after
{"server_remote": "https://..."}
$ bd doctor
Defensive patterns

Strategy: validation

Validate before calling

var meta map[string]any
raw, err := os.ReadFile(filepath.Join(beadsDir, "config", "metadata.json"))
if err != nil {
    return err
}
if err := json.Unmarshal(raw, &meta); err != nil {
    return fmt.Errorf("metadata.json corrupt: %w", err)
}

Prevention

When it happens

Trigger: Running any data command where <beadsDir>/config/metadata.json exists but is malformed JSON, has invalid fields, or cannot be read due to permissions; detected by loadServerModeFromBeadsDir during command-context preparation.

Common situations: A crashed sync or interrupted `bd dolt pull` left metadata.json half-written; manual editing broke JSON syntax; disk-full during a previous write; file ownership/permission issues after user switch.

Related errors


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