{"record":{"id":"4abeae9be9aa6460","repo":"gastownhall/beads","slug":"loading-config-for-gate-resolution-w","errorCode":null,"errorMessage":"loading config for gate resolution: %w","messagePattern":"loading config for gate resolution: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/doltserver/physical_root.go","lineNumber":263,"sourceCode":"// file's parent itself (and refuses symlinked roots), and resolving here too\n// would double-handle and could disagree with the gate's own rules.\nfunc ResolvePhysicalRoots(beadsDir string) (PhysicalRoots, error) {\n\tabs, err := filepath.Abs(beadsDir)\n\tif err != nil {\n\t\treturn PhysicalRoots{}, fmt.Errorf(\"resolving beads dir %s: %w\", beadsDir, err)\n\t}\n\tabs = filepath.Clean(abs)\n\tpr := PhysicalRoots{BeadsDir: abs}\n\n\t// Side-effect-free config load: never trigger the legacy config.json\n\t// migration. Absent metadata.json is treated as cfg == nil.\n\tvar cfg *configfile.Config\n\tif _, statErr := os.Stat(configfile.ConfigPath(abs)); statErr == nil {\n\t\tloaded, loadErr := configfile.Load(abs)\n\t\tif loadErr != nil {\n\t\t\t// A present-but-broken metadata.json is authoritative: the open\n\t\t\t// path refuses to fall back, so gate planning refuses to guess.\n\t\t\treturn PhysicalRoots{}, fmt.Errorf(\"loading config for gate resolution: %w\", loadErr)\n\t\t}\n\t\tcfg = loaded\n\t}\n\n\taddRoot := func(root string) error {\n\t\trootAbs, aerr := filepath.Abs(root)\n\t\tif aerr != nil {\n\t\t\treturn fmt.Errorf(\"resolving physical root %s: %w\", root, aerr)\n\t\t}\n\t\tpr.Roots = append(pr.Roots, filepath.Clean(rootAbs))\n\t\treturn nil\n\t}\n\n\tswitch {\n\tcase cfg != nil && cfg.IsDoltProxiedServerMode():\n\t\tpr.Mode = \"proxied-server\"\n\t\troot, perr := ResolveProxiedServerRootPath(abs)\n\t\tif perr != nil {","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/doltserver/physical_root.go#L245-L281","documentation":"ResolvePhysicalRoots wraps configfile.Load(abs) failures as \"loading config for gate resolution: %w\". A present metadata.json (configfile.ConfigPath) is treated as authoritative: if it exists but cannot be parsed or loaded, gate planning refuses to guess or fall back — matching the open path's behavior of never silently falling back on broken metadata. This surfaces corrupted or hand-edited metadata.json files early.","triggerScenarios":"ResolvePhysicalRoots finds configfile.ConfigPath(abs) exists, calls configfile.Load, and load fails: invalid JSON, wrong types after manual editing, truncated file from a crash/partial write, or a schema version the current code cannot read.","commonSituations":"User hand-edited .beads/metadata.json and introduced a JSON syntax error; an interrupted bd process left a truncated metadata.json; an older/newer bd wrote a field type the current version rejects.","solutions":["Open .beads/metadata.json in a JSON linter (jq . metadata.json) and fix the syntax/type error.","If the file is truncated, restore it from git history or a backup; otherwise delete it and let bd recreate defaults (losing server metadata like PID/port).","Check for concurrent writers: ensure no other bd process was mid-write; re-run after it exits.","Validate with the same bd version that wrote the file; upgrade bd if the schema is newer."],"exampleFix":"// before\n$ cat .beads/metadata.json\n{\"serverPid\": 1234, \"port\": }        // truncated\n// after\n$ bd doctor   # or fix manually\n$ vi .beads/metadata.json\n{\"serverPid\": 1234, \"port\": 8123}\n$ bd start","handlingStrategy":"type-guard","validationCode":"path := configfile.ConfigPath(abs)\nif data, err := os.ReadFile(path); err == nil {\n    var v map[string]any\n    if err := json.Unmarshal(data, &v); err != nil {\n        return fmt.Errorf(\"metadata.json is not valid JSON: %v\", err)\n    }\n}","typeGuard":"func metadataParses(path string) bool {\n    data, err := os.ReadFile(path)\n    if err != nil { return false }\n    var v map[string]any\n    return json.Unmarshal(data, &v) == nil\n}","tryCatchPattern":"roots, err := ResolvePhysicalRoots(beadsDir)\nif err != nil {\n    if strings.Contains(err.Error(), \"loading config for gate resolution\") {\n        return fmt.Errorf(\"%s is corrupt; restore from backup or delete to regenerate\", configfile.ConfigPath(abs))\n    }\n    return err\n}","preventionTips":["Never hand-edit metadata.json while bd is running","Validate JSON (jq . metadata.json) after any manual edit","Back up metadata.json before bd upgrades","Investigate truncated files after crashes — rewrite them cleanly"],"tags":["configuration","json","metadata","validation"],"backgroundTag":"config-load-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}