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
- Verify the directory path exists: ls <dir>
- Use the correct built-in themes location or an absolute path
- Fix file permissions (chmod/chown) so the current user can read the directory
- 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
- Use absolute paths for theme directories
- Check the directory exists in CI/containers before running
- Fix read permissions after copying themes as root
- Verify flags/env vars supplying the dir for typos
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
- no theme files found in %s
- failed to create directory %s: %w
- failed to write configuration file %s: %w
- failed to read data file: %w
- unable to delete font file after registry key open error
AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31).
Data as JSON: /api/errors/90071502e4971db4.
Report an issue: GitHub.