JanDeDobbeleer/oh-my-posh · error
failed to write configuration file %s: %w
Error message
failed to write configuration file %s: %w
What it means
Configuration.Apply writes the exported config data with os.WriteFile; when that write fails, the error is wrapped with the target file path. The underlying syscall error (permission denied, disk full, target is a directory, read-only volume) is available via %w/errors.Unwrap or errors.As(*fs.PathError).
Source
Thrown at src/cli/dsc/config.go:96
return fmt.Errorf("source file %s does not match format %s", c.Source, c.Format)
}
log.Debug("Applying configuration %s", c.Source)
// Expand tilde to home directory for file operations
filePath := strings.ReplaceAll(c.Source, "~", path.Home())
// Create directory if it doesn't exist
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed to create directory %s: %w", dir, err)
}
data := c.Export(c.Format)
// Write file
if err := os.WriteFile(filePath, []byte(data), 0644); err != nil {
return fmt.Errorf("failed to write configuration file %s: %w", filePath, err)
}
log.Debug("Configuration written to %s", filePath)
return nil
}
func (c *Configuration) Equal(other *Configuration) bool {
if other == nil {
return false
}
return c.Source == other.Source
}
func (c *Configuration) Resolve() (*Configuration, bool) {
log.Debug("Resolving configuration %s", c.Source)
if c.resolved {View on GitHub (pinned to 0976794618)
Solutions
- Check the wrapped error and the path in the message: confirm the path is a file, not a directory, and that you have write permission
- Fix ownership/permissions (chown/chmod) or delete the read-only/locked file so WriteFile can recreate it
- Free disk space if the error indicates the volume is full
- Run elevated only if the destination genuinely requires it; otherwise point Source at a user-writable location
Example fix
// before: file owned by root -rw-r--r-- root root ~/.config/oh-my-posh/config.omp.json // after sudo chown $USER ~/.config/oh-my-posh/config.omp.json
Defensive patterns
Strategy: validation
Validate before calling
target := strings.ReplaceAll(source, "~", home)
if st, err := os.Stat(target); err == nil && st.IsDir() {
return fmt.Errorf("%s is a directory, expected a file", target)
}
if st, err := os.Stat(target); err == nil {
f, err := os.OpenFile(target, os.O_WRONLY, 0)
if err != nil { return fmt.Errorf("cannot write %s: %w", target, err) }
f.Close()
} Try / catch
if err := cfg.Apply(); err != nil {
var perr *fs.PathError
if errors.As(err, &perr) {
switch {
case errors.Is(perr.Err, fs.ErrPermission):
return fmt.Errorf("fix permissions or ownership of %s", perr.Path)
case errors.Is(perr.Err, syscall.ENOSPC):
return fmt.Errorf("disk full: free space and retry")
}
}
return err
} Prevention
- Ensure the config file is owned by the current user, not root
- Do not set the read-only bit on theme/config files you expect dsc to rewrite
- Keep enough free disk space; watch for ENOSPC in CI volumes
- Confirm the Source path ends in a filename, not a directory
When it happens
Trigger: Applying a DSC Configuration where the destination path exists as a directory, the user lacks write permission on the file or its directory, or the filesystem is read-only/full.
Common situations: Config file previously created by root so a normal user cannot overwrite it; Windows file locked by another process; overwriting a read-only file; destination path accidentally points at a directory name.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- failed to create directory %s: %w
- unable to delete font file after registry key open error
- we do not have permissions to update
- unable to create fonts directory: %s
- unable to write font file: %s
AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31).
Data as JSON: /api/errors/c4de1c25ed02f67c.
Report an issue: GitHub.