gastownhall/beads · error
failed to write config.yaml: %w
Error message
failed to write config.yaml: %w
What it means
setYamlConfigAtPath wraps any os.WriteFile failure after successfully computing the updated YAML content. The file was read fine but writing the merged content back failed; the OS-level cause is preserved via %w. bd throws it because a failed write would silently drop the config change.
Source
Thrown at internal/config/yaml_config.go:526
// Normalize key to canonical yaml format
normalizedKey := normalizeYamlKey(key)
// Read existing config
content, err := os.ReadFile(configPath) //nolint:gosec // configPath is from findProjectConfigYaml
if err != nil {
return fmt.Errorf("failed to read config.yaml: %w", err)
}
// Update or add the key
newContent, err := updateYamlKey(string(content), normalizedKey, value)
if err != nil {
return err
}
// Write back
if err := os.WriteFile(configPath, []byte(newContent), 0600); err != nil { //nolint:gosec // configPath is validated
return fmt.Errorf("failed to write config.yaml: %w", err)
}
return nil
}
// GetYamlConfig gets a configuration value from config.yaml.
// Returns empty string if key is not found or is commented out.
// Keys are normalized to their canonical yaml format (e.g., sync.branch -> sync-branch).
func GetYamlConfig(key string) string {
if v == nil {
return ""
}
normalizedKey := normalizeYamlKey(key)
return v.GetString(normalizedKey)
}
// UnsetYamlConfig removes a configuration value from the project's config.yaml file.
// The key line is commented out (prefixed with "# ") to preserve it as documentation.View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause: 'permission denied' -> chmod/chown config.yaml so the current user can write (chmod u+w .beads/config.yaml)
- Free disk space or resolve quota if the cause is ENOSPC
- Ensure config.yaml is a regular file, not a directory or broken symlink
- Re-run the command with the appropriate user/credentials (e.g., not sudo-stripped ownership)
Example fix
// before (fails: read-only file) $ bd config set dolt.shared-server false failed to write config.yaml: ... permission denied // after $ chmod u+w .beads/config.yaml $ bd config set dolt.shared-server false
Defensive patterns
Strategy: try-catch
Validate before calling
fi, err := os.Stat(configPath)
if err != nil || !fi.Mode().IsRegular() {
return fmt.Errorf("config.yaml not writable-regular: %s", configPath)
}
if err := syscall.Access(configPath, syscall.O_RDWR); err != nil {
return fmt.Errorf("no write permission on %s", configPath)
} Type guard
func configWritable(path string) bool {
f, err := os.OpenFile(path, os.O_WRONLY, 0)
if err != nil { return false }
f.Close()
return true
} Try / catch
if err := SetYamlConfig(key, value); err != nil {
if errors.Is(err, os.ErrPermission) { /* fix perms */ }
if errors.Is(err, syscall.ENOSPC) { /* free disk */ }
return err
} Prevention
- Keep config.yaml owned by the user running bd (avoid sudo-induced ownership drift)
- Monitor disk space in CI environments before config writes
- Never replace config.yaml with a directory or read-only artifact in build pipelines
When it happens
Trigger: Calling SetYamlConfig / SetYamlConfigInDir / SetUserYamlConfig when the config.yaml file or its containing directory is read-only, the disk is full, the path became a directory, or the process lacks write permission (mode 0600 write by a different user).
Common situations: Running bd as a non-root user against a root-owned config.yaml; read-only mount or checked-out repo with read-only .beads/config.yaml; disk quota exceeded in CI containers.
Related errors
- failed to save config: %w
- failed to read config.yaml: %w
- open log file %q: %w
- dolt path is not executable
- server: NewDoltServer: doltBinExec is required
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0caf636887dc2169.
Report an issue: GitHub.