gastownhall/beads · error
reading source: %w
Error message
reading source: %w
What it means
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).
Source
Thrown at cmd/bd/formula.go:675
return path
}
}
return ""
}
// formulaToTOML converts a Formula to TOML bytes.
// Uses a custom structure optimized for TOML readability.
func formulaToTOML(f *formula.Formula) ([]byte, error) {
// We need to re-read the original JSON to get the raw structure
// because the Formula struct loses some ordering/formatting
if f.Source == "" {
return nil, fmt.Errorf("formula has no source path")
}
// Read the original JSON
jsonData, err := os.ReadFile(f.Source)
if err != nil {
return nil, fmt.Errorf("reading source: %w", err)
}
// Parse into a map to preserve structure
var raw map[string]interface{}
if err := json.Unmarshal(jsonData, &raw); err != nil {
return nil, fmt.Errorf("parsing JSON: %w", err)
}
// Fix float64 to int for known integer fields
fixIntegerFields(raw)
// Encode to TOML
var buf bytes.Buffer
encoder := toml.NewEncoder(&buf)
encoder.Indent = ""
if err := encoder.Encode(raw); err != nil {
return nil, fmt.Errorf("encoding TOML: %w", err)
}View on GitHub (pinned to 71377f2769)
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.
Example fix
// before f.Source = "formulas/deploy.json" // relative, cwd changed // after f.Source = "/abs/path/to/.beads/formulas/deploy.json" // resolve relative to repo root
Defensive patterns
Strategy: validation
Validate before calling
// before conversion
if _, err := os.Stat(f.Source); err != nil {
return fmt.Errorf("formula source missing: %w", err)
} Try / catch
if _, err := formulaToTOML(f); err != nil {
if errors.Is(err, os.ErrNotExist) { /* regenerate or restore source JSON */ }
if errors.Is(err, os.ErrPermission) { /* fix permissions */ }
} Prevention
- 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.
When it happens
Trigger: Running `bd formula convert` (or convertAllFormulas) where the recorded Source path no longer exists, was moved/renamed, or is unreadable due to file permissions.
Common situations: 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.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- parsing formula: %w
- loading aspect %q: %w
- loading formula %q: %w
- inline expand on step %q: loading %q: %w
- formula %q not found in search paths
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/3dd2f7bad3799631.
Report an issue: GitHub.