{"record":{"id":"a3cbc9c5714dad78","repo":"gastownhall/beads","slug":"s-w","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/bootstrap.go","lineNumber":1058,"sourceCode":"}\n\n// findParentConfig walks up from beadsDir's parent looking for a\n// .beads/metadata.json in ancestor directories. This handles the case where a\n// rig subdirectory (its own git repo) doesn't have a local .beads but its\n// parent workspace does. Returns nil if no parent config is found. A malformed\n// or unreadable ancestor metadata file is authoritative and returned as an error;\n// bootstrap must not skip it and select a more distant workspace or defaults.\nfunc findParentConfig(beadsDir string) (*configfile.Config, error) {\n\t// Start from the parent of beadsDir's enclosing directory.\n\t// beadsDir is typically \"<project>/.beads\", so we start from <project>'s parent.\n\tstart := filepath.Dir(filepath.Dir(beadsDir))\n\thomeDir, _ := os.UserHomeDir()\n\n\tfor dir := start; dir != \"/\" && dir != \".\"; {\n\t\tcandidate := filepath.Join(dir, \".beads\")\n\t\tcfg, err := configfile.LoadForDiscovery(candidate)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%s: %w\", configfile.ConfigPath(candidate), err)\n\t\t}\n\t\tif cfg != nil {\n\t\t\tif err := guardLegacyUpgradeWorkspace(candidate); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn cfg, nil\n\t\t}\n\n\t\t// Don't search above $HOME\n\t\tif homeDir != \"\" && dir == homeDir {\n\t\t\tbreak\n\t\t}\n\n\t\tparent := filepath.Dir(dir)\n\t\tif parent == dir {\n\t\t\tbreak\n\t\t}\n\t\tdir = parent","sourceCodeStart":1040,"sourceCodeEnd":1076,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/bootstrap.go#L1040-L1076","documentation":"findParentConfig walks up from a start directory looking for a `.beads` config, and wraps any error from configfile.LoadForDiscovery with the candidate config path via `%s: %w`. It exists so users can see exactly which `.beads` config file failed to load during ancestor-directory discovery. The wrapped error typically indicates a corrupt or unreadable config JSON.","triggerScenarios":"Running bd commands in (or under) a directory where some ancestor directory has a `.beads/config.json` that fails to load — malformed JSON, unreadable permissions, or a corrupt file — while findParentConfig walks up from the working directory.","commonSituations":"A partially-written or hand-edited .beads/config.json; a config file truncated by a crashed process or disk-full; wrong file permissions after copying a repo as root; running inside a worktree or subdir where an ancestor's stale config is corrupt.","solutions":["Open the path named in the error message and fix or validate the .beads config JSON (e.g. `jq . .beads/config.json`).","If the ancestor config is stale/unwanted, delete or repair that `.beads` directory.","Restore read permissions on the config file (chmod/chown).","Re-run the command; if discovery should skip corrupt ancestors, note existing tests cover TestFindParentConfigDoesNotSkipCorruptNearestAncestor behavior."],"exampleFix":"// before: corrupt config discovered\n/home/user/proj/.beads/config.json: unexpected end of JSON input\n// after: repair the file\njq . /home/user/proj/.beads/config.json  # find the syntax error, fix it","handlingStrategy":"try-catch","validationCode":"if [ -f .beads/config.json ]; then jq -e . .beads/config.json >/dev/null || echo 'corrupt config'; fi","typeGuard":"func validBeadsConfig(dir string) bool {\n\t_, err := configfile.LoadForDiscovery(filepath.Join(dir, \".beads\"))\n\treturn err == nil\n}","tryCatchPattern":"cfg, err := findParentConfig(start)\nif err != nil {\n\tvar pathErr *os.PathError\n\tif errors.As(err, &pathErr) { /* handle unreadable path */ }\n\treturn fmt.Errorf(\"bootstrap discovery failed: %w\", err)\n}","preventionTips":["Validate .beads/config.json with jq after editing","Never hand-edit configs without a backup","Watch for disk-full/crash truncation of config writes"],"tags":["config","discovery","filesystem"],"backgroundTag":"config-file-load-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}