{"record":{"id":"9fd25f6267f8c3d0","repo":"gastownhall/beads","slug":"failed-to-load-s-w-no-storage-database-was-ope","errorCode":null,"errorMessage":"failed to load %s: %w; no storage database was opened or modified; fix or restore metadata.json and retry","messagePattern":"failed to load (.+?): %w; no storage database was opened or modified; fix or restore metadata\\.json and retry","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/doctor.go","lineNumber":372,"sourceCode":"\tdoctorCmd.Flags().BoolVar(&doctorAgent, \"agent\", false, \"Agent-facing diagnostic mode: rich context for AI agents (ZFC-compliant)\")\n}\n\nfunc shouldSkipDoctorNetworkChecks() bool {\n\treturn jsonOutput || !ui.IsTerminal()\n}\n\n// validateDoctorWorkspaceBackend keeps doctor diagnostics read-only when metadata\n// selects a removed or unknown implementation or cannot be parsed. Doctor contains\n// direct diagnostic store paths and may run under shared-server mode, so corrupt\n// metadata must be rejected before version tracking or any database check begins.\nfunc validateDoctorWorkspaceBackend(path string) error {\n\tbeadsDir := doctor.ResolveBeadsDirForRepo(path)\n\tif err := guardLegacyUpgradeWorkspace(beadsDir); err != nil {\n\t\treturn err\n\t}\n\tcfg, err := configfile.LoadForDiscovery(beadsDir)\n\tif err != nil {\n\t\treturn 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)\n\t}\n\treturn validateConfiguredBackend(cfg)\n}\n\n// printLegacyUpgradeDiagnostic preserves doctor as a store-free repair path:\n// the workspace is recognized, but no storage or metadata migration is opened.\nfunc printLegacyUpgradeDiagnostic(err error) error {\n\tif jsonOutput || doctorAgent {\n\t\treturn outputJSON(map[string]any{\n\t\t\t\"status\":  \"warning\",\n\t\t\t\"code\":    \"legacy_upgrade_required\",\n\t\t\t\"message\": err.Error(),\n\t\t\t\"guide\":   \"docs/getting-started/upgrading.md#cross-era-upgrades\",\n\t\t})\n\t}\n\t_, _ = fmt.Fprintf(os.Stdout, \"Warning: %v\\n\", err)\n\t_, _ = fmt.Fprintln(os.Stdout, \"Follow docs/getting-started/upgrading.md#cross-era-upgrades for the layout-specific migration path.\")\n\treturn nil","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor.go#L354-L390","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect .beads/metadata.json (path is printed in the error) and fix JSON syntax or missing fields.","Restore metadata.json from git history or a backup: git checkout -- .beads/metadata.json.","Resolve any merge-conflict markers (<<<<<<<) left in the file.","If unrecoverable, recreate the config via 'bd init' (or copy from a healthy workspace) and re-run doctor.","Check file permissions so the current user can read .beads/metadata.json."],"exampleFix":"// before: conflicted/partial config\n{<<<<<<< HEAD\n  \"backend\": \"dolt\"\n// after: valid config\n{\n  \"backend\": \"dolt\"\n}","handlingStrategy":"validation","validationCode":"data, err := os.ReadFile(filepath.Join(beadsDir, \"metadata.json\"))\nif err != nil { return err }\nvar cfg map[string]any\nif err := json.Unmarshal(data, &cfg); err != nil {\n    return fmt.Errorf(\"metadata.json is not valid JSON: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"cfg, err := configfile.LoadForDiscovery(beadsDir)\nif err != nil {\n    // safe: nothing was opened or modified\n    restored, rerr := restoreConfigFromGit(beadsDir)\n    if rerr != nil { return err }\n    cfg = restored\n}","preventionTips":["Track .beads/metadata.json in git so it can be restored after bad edits.","Validate JSON after hand-editing (jq . metadata.json).","Resolve merge conflicts in metadata.json before running bd commands.","Use matching bd versions across machines sharing a workspace.","Avoid interrupting 'bd init' so the config is written completely."],"tags":["go","configuration","metadata-json","doctor"],"backgroundTag":"config-file-load-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}