{"record":{"id":"cf960a0c259aff7a","repo":"gastownhall/beads","slug":"ensure-user-config-w","errorCode":null,"errorMessage":"ensure user config: %w","messagePattern":"ensure user config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/metrics/userconfig.go","lineNumber":22,"sourceCode":"\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/steveyegge/beads/internal/config\"\n)\n\nvar commentedMetricsRe = regexp.MustCompile(`(?m)^\\s*#\\s*metrics\\s*:`)\n\nfunc EnsureUserConfigDefaults() error {\n\tpath, err := config.UserConfigYamlPath()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"ensure user config: %w\", err)\n\t}\n\n\tdata, err := os.ReadFile(path) //nolint:gosec // path is a validated absolute user config path\n\tif errors.Is(err, fs.ErrNotExist) {\n\t\treturn writeUserConfigBootstrap(path)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"ensure user config: read %s: %w\", path, err)\n\t}\n\n\tif commentedMetricsRe.Match(data) {\n\t\treturn nil\n\t}\n\n\tvar root yaml.Node\n\tif err := yaml.Unmarshal(data, &root); err != nil {\n\t\treturn fmt.Errorf(\"ensure user config: parse %s: %w\", path, err)\n\t}","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/metrics/userconfig.go#L4-L40","documentation":"EnsureUserConfigDefaults ensures the user's bd config YAML exists and contains the metrics defaults block. If the config path itself cannot be determined (config.UserConfigYamlPath fails), it wraps the cause as 'ensure user config: ...'. It cannot proceed to read or bootstrap the file without a resolved path.","triggerScenarios":"Calling EnsureUserConfigDefaults when config.UserConfigYamlPath returns an error — typically HOME unset or an XDG config path resolution failure. Callers include writeUserConfigBootstrap and the EnsureUserConfigDefaults test suite.","commonSituations":"Running bd in a container/CI with HOME unset; malformed XDG_CONFIG_HOME pointing somewhere unusable; environment where user config conventions cannot be satisfied.","solutions":["Set HOME (and optionally XDG_CONFIG_HOME) to a writable location before running bd.","Ensure the resolved config directory exists and is writable.","Inspect the wrapped cause (%w) for the exact path-resolution error."],"exampleFix":"// before\nerr := metrics.EnsureUserConfigDefaults() // fails when HOME unset\n// after\nif os.Getenv(\"HOME\") == \"\" {\n    os.Setenv(\"HOME\", \"/home/agent\")\n}\nerr := metrics.EnsureUserConfigDefaults()","handlingStrategy":"fallback","validationCode":"if os.Getenv(\"HOME\") == \"\" && os.Getenv(\"XDG_CONFIG_HOME\") == \"\" {\n    return fmt.Errorf(\"cannot locate user config: HOME/XDG_CONFIG_HOME unset\")\n}","typeGuard":null,"tryCatchPattern":"if err := metrics.EnsureUserConfigDefaults(); err != nil {\n    if strings.HasPrefix(err.Error(), \"ensure user config\") {\n        return nil // skip defaults; config path unavailable\n    }\n    return err\n}","preventionTips":["Set HOME before running bd in minimal environments.","Pre-create the config directory.","Treat config-defaults bootstrap as best-effort, not fatal."],"tags":["metrics","configuration","config-path","filesystem"],"backgroundTag":"config-path-resolution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}