gastownhall/beads · error
failed to encode config.yaml: %w
Error message
failed to encode config.yaml: %w
What it means
SetReposInYAML re-encodes the modified yaml.Node tree via a yaml.Encoder. If Encode fails (rare — usually only from invalid node contents such as a nil/invalid node in the tree), the error is wrapped as "failed to encode config.yaml".
Source
Thrown at internal/config/repos.go:144
// Remove repos section entirely if empty
mapping.Content = append(mapping.Content[:reposIndex], mapping.Content[reposIndex+2:]...)
} else {
mapping.Content[reposIndex+1] = reposNode
}
} else if reposNode != nil {
// Add new repos section at the end
mapping.Content = append(mapping.Content,
&yaml.Node{Kind: yaml.ScalarNode, Value: "repos"},
reposNode,
)
}
// Marshal back to YAML
var buf strings.Builder
encoder := yaml.NewEncoder(&buf)
encoder.SetIndent(2)
if err := encoder.Encode(&root); err != nil {
return fmt.Errorf("failed to encode config.yaml: %w", err)
}
if err := encoder.Close(); err != nil {
return fmt.Errorf("failed to close encoder: %w", err)
}
// Write back to file
if err := os.WriteFile(configPath, []byte(buf.String()), 0600); err != nil {
return fmt.Errorf("failed to write config.yaml: %w", err)
}
// Reload viper config so changes take effect immediately
if v != nil {
if err := v.ReadInConfig(); err != nil {
// Not fatal - config is on disk, will be picked up on next command
_ = err // Best effort: viper reload failure is non-fatal since config was already written to disk
}
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the code that builds/mutates the yaml.Node tree for zero-value nodes (Kind must be set)
- Ensure all nodes appended carry a valid Kind, Style, and Value/Content
- Upgrade gopkg.in/yaml.v3 — some encode bugs were fixed in later versions
- If reproducible, marshal a plain struct instead of a Node tree to isolate the bad value
Example fix
// before
node := yaml.Node{} // Kind not set -> encode error
// after
node := yaml.Node{Kind: yaml.ScalarNode, Value: repoPath} Defensive patterns
Strategy: try-catch
Try / catch
if err := SetReposInYAML(cfgPath, repos); err != nil {
if strings.Contains(err.Error(), "failed to encode") {
log.Printf("node tree invalid, update yaml.v3: %v", err)
}
return err
} Prevention
- Pin gopkg.in/yaml.v3 to a recent version
- Only insert fully-populated yaml.Node values (set Kind/Style/Value)
- Prefer building config from typed structs when structure preservation is not needed
- Report reproducible encode failures upstream
When it happens
Trigger: encoder.Encode(&root) returns an error, typically from an invalid yaml.Node value inserted into the tree (e.g. zero-value nodes with Kind 0) or an unencodable value.
Common situations: A custom build or patched config-construction code injected an invalid node; running against a corrupted in-memory tree rather than a user mistake in most cases.
Related errors
- 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
- error reading config file: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/922ca43ec7fb47f6.
Report an issue: GitHub.