JanDeDobbeleer/oh-my-posh · error

failed to read themes directory %s: %w

Error message

failed to read themes directory %s: %w

What it means

ThemeFiles(dir) lists theme files in a directory for the config data merge feature. If os.ReadDir fails (directory missing, no permissions, wrong path), the OS error is wrapped with this message so callers know the themes directory itself could not be read.

Source

Thrown at src/config/data.go:50

	DataVersionKey  = "version"
	DataEnvKey      = "env"
	DataSegmentsKey = "segments"
)

// ThemeFileExtensions is every extension a bundled theme file is recognized
// by: mirrors website/export_themes.mjs's THEME_EXTENSIONS, the third copy of
// this list living outside this repo's Go code.
var ThemeFileExtensions = []string{".omp.json", ".omp.toml", ".omp.yaml"}

// ThemeFiles enumerates the theme files in dir, sorted so a caller merging or
// comparing across all of them (cli's --themes merge mode, prompt's
// golden-fixture harness) gets a deterministic order - for the merge mode
// specifically, so mergeRichest's first-seen tie-break consistently favors
// the alphabetically first theme.
func ThemeFiles(dir string) ([]string, error) {
	entries, err := os.ReadDir(dir)
	if err != nil {
		return nil, fmt.Errorf("failed to read themes directory %s: %w", dir, err)
	}

	var files []string

	for _, entry := range entries {
		if entry.IsDir() {
			continue
		}

		name := entry.Name()

		for _, ext := range ThemeFileExtensions {
			if strings.HasSuffix(name, ext) {
				files = append(files, filepath.Join(dir, name))
				break
			}
		}
	}

View on GitHub (pinned to 0976794618)

Solutions

  1. Verify the directory path exists: ls <dir>
  2. Use the correct built-in themes location or an absolute path
  3. Fix file permissions (chmod/chown) so the current user can read the directory
  4. Check the flag/env var supplying the directory for typos

Example fix

// before
oh-my-posh config export --themes-dir ./themnes
// after
oh-my-posh config export --themes-dir ./themes
Defensive patterns

Strategy: try-catch

Validate before calling

stat, err := os.Stat(dir)
if err != nil || !stat.IsDir() {
    return fmt.Errorf("themes directory %s is missing or not a directory", dir)
}

Type guard

func isReadableDir(path string) bool {
    info, err := os.Stat(path)
    return err == nil && info.IsDir()
}

Try / catch

files, err := config.ThemeFiles(dir)
if err != nil && strings.Contains(err.Error(), "failed to read themes directory") {
    log.Fatalf("themes dir %q unreadable: %v", dir, errors.Unwrap(err))
}

Prevention

When it happens

Trigger: Passing a nonexistent or non-directory path as the themes directory, pointing at a path without read permission, or a misconfigured environment flag supplying the wrong dir.

Common situations: Typo in the themes path, running from a different working directory than assumed, Docker/CI containers missing the themes directory, or permission-restricted install locations.

Related errors


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