gastownhall/beads · error
failed to parse config.yaml: %w
Error message
failed to parse config.yaml: %w
What it means
GetReposFromYAML unmarshals config.yaml into a generic map; this error wraps any yaml.Unmarshal failure, meaning the file exists and is readable but is not valid YAML (or the top level is not a mapping).
Source
Thrown at internal/config/repos.go:47
}
return configPath, nil
}
// GetReposFromYAML reads the repos configuration from config.yaml
// Returns an empty ReposConfig if repos section doesn't exist
func GetReposFromYAML(configPath string) (*ReposConfig, error) {
data, err := os.ReadFile(configPath) // #nosec G304 - config file path from caller
if err != nil {
if os.IsNotExist(err) {
return &ReposConfig{}, nil
}
return nil, fmt.Errorf("failed to read config.yaml: %w", err)
}
// Parse into a generic map to extract repos section
var cfg map[string]interface{}
if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("failed to parse config.yaml: %w", err)
}
repos := &ReposConfig{}
if reposRaw, ok := cfg["repos"]; ok && reposRaw != nil {
reposMap, ok := reposRaw.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("repos section is not a map")
}
if primary, ok := reposMap["primary"].(string); ok {
repos.Primary = primary
}
if additional, ok := reposMap["additional"]; ok && additional != nil {
switch v := additional.(type) {
case []interface{}:
for _, item := range v {
if str, ok := item.(string); ok {View on GitHub (pinned to 71377f2769)
Solutions
- Validate the YAML with a linter: yamllint .beads/config.yaml or an online parser.
- Fix indentation — use spaces, never tabs — and remove merge-conflict markers.
- Restore a known-good config from git: git checkout -- .beads/config.yaml or git diff to see what changed.
- If unparseable content is unrecoverable, back it up and re-run `bd init` to regenerate.
Example fix
// before (broken)
repos:
primary: "."
// after
repos:
primary: "."
additional:
- "../other-repo" Defensive patterns
Strategy: validation
Validate before calling
data, err := os.ReadFile(".beads/config.yaml")
if err == nil {
var probe map[string]interface{}
if err := yaml.Unmarshal(data, &probe); err != nil {
return fmt.Errorf("config.yaml is invalid YAML: %w", err)
}
} Try / catch
repos, err := config.GetReposFromYAML(configPath)
if err != nil && strings.Contains(err.Error(), "failed to parse config.yaml") {
return fmt.Errorf("config.yaml is malformed; restore from git: %w", err)
} Prevention
- Validate config.yaml after every hand edit (yamllint or editor plugin).
- Use spaces, not tabs, for YAML indentation.
- Resolve merge conflicts in .beads/config.yaml before running bd commands.
When it happens
Trigger: Calling GetReposFromYAML(configPath) where the file contains malformed YAML — bad indentation, tabs instead of spaces, unterminated quotes, duplicate keys rejected by yaml.v3, or a top-level scalar/list instead of a mapping.
Common situations: Hand-editing config.yaml and breaking indentation; merging conflicts leaving conflict markers (<<<<<<<) in the file; a tool writing non-YAML content into config.yaml; pasting JSON with tabs or trailing issues.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- error reading config file: %w
- persist sync.remote to config.yaml: %w
- failed to persist sync.remote to config.yaml: %w
- failed to persist sync.remote to config.yaml: %v
- failed to configure hydration: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1661f040f44d7b98.
Report an issue: GitHub.