gastownhall/beads · error

failed to load %s: %w; no storage database was opened or mod

Error message

failed to load %s: %w; no storage database was opened or modified; fix or restore metadata.json and retry

What it means

validateDoctorWorkspaceBackend is a store-free doctor path: it resolves the .beads directory, runs the legacy-upgrade guard, then loads .beads/metadata.json via configfile.LoadForDiscovery BEFORE any database is opened. If metadata.json cannot be loaded or parsed, this wrapped error is returned, explicitly stating that no storage database was opened or modified — doctor remains a safe repair path.

Source

Thrown at cmd/bd/doctor.go:372

	doctorCmd.Flags().BoolVar(&doctorAgent, "agent", false, "Agent-facing diagnostic mode: rich context for AI agents (ZFC-compliant)")
}

func shouldSkipDoctorNetworkChecks() bool {
	return jsonOutput || !ui.IsTerminal()
}

// validateDoctorWorkspaceBackend keeps doctor diagnostics read-only when metadata
// selects a removed or unknown implementation or cannot be parsed. Doctor contains
// direct diagnostic store paths and may run under shared-server mode, so corrupt
// metadata must be rejected before version tracking or any database check begins.
func validateDoctorWorkspaceBackend(path string) error {
	beadsDir := doctor.ResolveBeadsDirForRepo(path)
	if err := guardLegacyUpgradeWorkspace(beadsDir); err != nil {
		return err
	}
	cfg, err := configfile.LoadForDiscovery(beadsDir)
	if err != nil {
		return fmt.Errorf("failed to load %s: %w; no storage database was opened or modified; fix or restore metadata.json and retry", configfile.ConfigPath(beadsDir), err)
	}
	return validateConfiguredBackend(cfg)
}

// printLegacyUpgradeDiagnostic preserves doctor as a store-free repair path:
// the workspace is recognized, but no storage or metadata migration is opened.
func printLegacyUpgradeDiagnostic(err error) error {
	if jsonOutput || doctorAgent {
		return outputJSON(map[string]any{
			"status":  "warning",
			"code":    "legacy_upgrade_required",
			"message": err.Error(),
			"guide":   "docs/getting-started/upgrading.md#cross-era-upgrades",
		})
	}
	_, _ = fmt.Fprintf(os.Stdout, "Warning: %v\n", err)
	_, _ = fmt.Fprintln(os.Stdout, "Follow docs/getting-started/upgrading.md#cross-era-upgrades for the layout-specific migration path.")
	return nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect .beads/metadata.json (path is printed in the error) and fix JSON syntax or missing fields.
  2. Restore metadata.json from git history or a backup: git checkout -- .beads/metadata.json.
  3. Resolve any merge-conflict markers (<<<<<<<) left in the file.
  4. If unrecoverable, recreate the config via 'bd init' (or copy from a healthy workspace) and re-run doctor.
  5. Check file permissions so the current user can read .beads/metadata.json.

Example fix

// before: conflicted/partial config
{<<<<<<< HEAD
  "backend": "dolt"
// after: valid config
{
  "backend": "dolt"
}
Defensive patterns

Strategy: validation

Validate before calling

data, err := os.ReadFile(filepath.Join(beadsDir, "metadata.json"))
if err != nil { return err }
var cfg map[string]any
if err := json.Unmarshal(data, &cfg); err != nil {
    return fmt.Errorf("metadata.json is not valid JSON: %w", err)
}

Try / catch

cfg, err := configfile.LoadForDiscovery(beadsDir)
if err != nil {
    // safe: nothing was opened or modified
    restored, rerr := restoreConfigFromGit(beadsDir)
    if rerr != nil { return err }
    cfg = restored
}

Prevention

When it happens

Trigger: Running 'bd doctor' (or the anonymous caller path) in a workspace whose .beads/metadata.json is missing required fields, malformed JSON, unreadable (permissions), or written by an incompatible bd version.

Common situations: Hand-edited metadata.json with invalid JSON; interrupted 'bd init' leaving a partial config; permission changes on .beads; older/newer bd writing config fields this version cannot parse; git merge conflicts inside metadata.json.

Related errors


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