gastownhall/beads · error
failed to close encoder: %w
Error message
failed to close encoder: %w
What it means
After encoding, SetReposInYAML must call encoder.Close() to flush the encoder's internal buffer into the strings.Builder. If Close returns an error, the encoded YAML may be incomplete and the error is wrapped as "failed to close encoder".
Source
Thrown at internal/config/repos.go:147
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
}
}
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Check the underlying writer for failures if a non-default writer is used
- Log the full wrapped error chain (%w) to identify the root cause
- Retry the operation — this is not a persistent config corruption
- Update gopkg.in/yaml.v3 to the latest version
Defensive patterns
Strategy: try-catch
Try / catch
if err := SetReposInYAML(cfgPath, repos); err != nil {
if strings.Contains(err.Error(), "failed to close encoder") {
log.Printf("transient encode-flush failure, retrying: %v", err)
return SetReposInYAML(cfgPath, repos)
}
return err
} Prevention
- Always use reliable in-memory writers (strings.Builder/bytes.Buffer) for encoding
- Keep yaml.v3 updated
- Check errors from both Encode and Close — never discard Close's error
- In tests, use writers that never fail to isolate logic from I/O errors
When it happens
Trigger: encoder.Close() returns an error after a successful Encode — in practice this happens when the underlying writer (strings.Builder never fails) or the encoder's internal flush/finish step fails, e.g. from a node state issue mid-flush.
Common situations: Encountered mainly with custom io.Writer implementations injected in tests that return errors on flush, or with yaml.v3 internal edge cases; rare in production use with strings.Builder.
Related errors
- failed to encode config.yaml: %w
- failed to read backup state: %w
- failed to write temp file: %w
- failed to sync temp file: %w
- persist sync.remote to config.yaml: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ace0cd64a3732e54.
Report an issue: GitHub.