{"record":{"id":"3dd2f7bad3799631","repo":"gastownhall/beads","slug":"reading-source-w","errorCode":null,"errorMessage":"reading source: %w","messagePattern":"reading source: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/formula.go","lineNumber":675,"sourceCode":"\t\t\treturn path\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// formulaToTOML converts a Formula to TOML bytes.\n// Uses a custom structure optimized for TOML readability.\nfunc formulaToTOML(f *formula.Formula) ([]byte, error) {\n\t// We need to re-read the original JSON to get the raw structure\n\t// because the Formula struct loses some ordering/formatting\n\tif f.Source == \"\" {\n\t\treturn nil, fmt.Errorf(\"formula has no source path\")\n\t}\n\n\t// Read the original JSON\n\tjsonData, err := os.ReadFile(f.Source)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"reading source: %w\", err)\n\t}\n\n\t// Parse into a map to preserve structure\n\tvar raw map[string]interface{}\n\tif err := json.Unmarshal(jsonData, &raw); err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing JSON: %w\", err)\n\t}\n\n\t// Fix float64 to int for known integer fields\n\tfixIntegerFields(raw)\n\n\t// Encode to TOML\n\tvar buf bytes.Buffer\n\tencoder := toml.NewEncoder(&buf)\n\tencoder.Indent = \"\"\n\tif err := encoder.Encode(raw); err != nil {\n\t\treturn nil, fmt.Errorf(\"encoding TOML: %w\", err)\n\t}","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/formula.go#L657-L693","documentation":"formulaToTOML reads the formula's original JSON file at f.Source with os.ReadFile before converting it to TOML. If that read fails — the file doesn't exist, the path is wrong, or permissions deny access — the error is wrapped as 'reading source: %w'. The underlying cause is preserved via %w for inspection with errors.Is/As (e.g. os.ErrNotExist).","triggerScenarios":"Running `bd formula convert` (or convertAllFormulas) where the recorded Source path no longer exists, was moved/renamed, or is unreadable due to file permissions.","commonSituations":"Source file deleted or moved after the formula was loaded; working directory changed so a relative path no longer resolves; permission changes after checkout or in CI containers running as a different user; formula JSON generated in a temp dir that was cleaned up.","solutions":["Verify the source JSON exists at f.Source (ls the path); restore or regenerate it if missing.","Run the command from the correct working directory if Source is a relative path.","Fix file permissions (chmod/chown) so the process can read the file.","Inspect the wrapped cause: errors.Is(err, os.ErrNotExist) vs permission errors to choose the fix."],"exampleFix":"// before\nf.Source = \"formulas/deploy.json\" // relative, cwd changed\n// after\nf.Source = \"/abs/path/to/.beads/formulas/deploy.json\" // resolve relative to repo root","handlingStrategy":"validation","validationCode":"// before conversion\nif _, err := os.Stat(f.Source); err != nil {\n    return fmt.Errorf(\"formula source missing: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := formulaToTOML(f); err != nil {\n    if errors.Is(err, os.ErrNotExist) { /* regenerate or restore source JSON */ }\n    if errors.Is(err, os.ErrPermission) { /* fix permissions */ }\n}","preventionTips":["Use absolute paths (or resolve relative to repo root) for formula sources.","Run conversion from the repository root where relative paths resolve.","Restore formula JSON from git if it was deleted or moved.","In CI, checkout the full repo including .beads/formulas before converting."],"tags":["formula","file-io","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}