JanDeDobbeleer/oh-my-posh · error

failed to create directory %s: %w

Error message

failed to create directory %s: %w

What it means

Configuration.Apply ensures the destination directory of the source path exists via os.MkdirAll before writing. When the OS refuses to create that directory (permission denied, read-only filesystem, path is an existing file, invalid path characters), the error is wrapped with the directory path. The wrapped %w contains the underlying syscall error.

Source

Thrown at src/cli/dsc/config.go:89

	formats := map[string][]string{
		config.JSON: {".json", ".jsonc"},
		config.YAML: {".yaml", ".yml"},
		config.TOML: {".toml", ".tml"},
	}

	if !slices.Contains(formats[c.Format], filepath.Ext(c.Source)) {
		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
	}

View on GitHub (pinned to 0976794618)

Solutions

  1. Read the wrapped %w error to see the exact OS reason (permission denied, not a directory, etc.)
  2. Create or fix permissions on the directory manually (mkdir -p, chmod/chown) or run with the privileges required
  3. Ensure no regular file exists at the directory path; rename or remove it
  4. Check that the drive/volume holding the path is mounted and writable, and that HOME resolves correctly

Example fix

// before: applying to /etc/oh-my-posh/config.omp.json as a non-root user
// after
sudo oh-my-posh dsc apply   # or target a writable path like ~/.config/oh-my-posh/
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(strings.ReplaceAll(source, "~", os.UserHomeDir()))
if st, err := os.Stat(dir); err == nil && !st.IsDir() {
    return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := os.MkdirAll(dir, 0o755); err != nil {
    return fmt.Errorf("pre-check: cannot create %s: %w", dir, err)
}

Try / catch

if err := cfg.Apply(); err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) && errors.Is(perr.Err, fs.ErrPermission) {
        return fmt.Errorf("need write access to %s: %w", perr.Path, err)
    }
    return err
}

Prevention

When it happens

Trigger: Applying a DSC Configuration whose target directory cannot be created: parent dir owned by root, target path component is an existing regular file, disk full, or a path with illegal characters on Windows.

Common situations: Storing the config in a system directory like /etc or C:\Windows without elevation; HOME pointing somewhere unwritable; a stale file occupying the directory name; network/removable drive not mounted.

Related errors


AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31). Data as JSON: /api/errors/67966d7cf7dc0378. Report an issue: GitHub.