JanDeDobbeleer/oh-my-posh · error

no theme files found in %s

Error message

no theme files found in %s

What it means

buildMergedDataDocument collects all theme files from the directory passed via --themes; when config.ThemeFiles returns an empty list, this error aborts the merged-fixture export because there is nothing to record. It is a plain error (no wrapped cause) naming the directory that contained no themes.

Source

Thrown at src/cli/config_export_data.go:392

// them into one fixture: for every env and segment key that appears in any
// theme, the richest recorded value wins (mergeRichest) - not the most common
// one. A fixture exists to exercise template logic, not to model a typical
// machine: a theme that never enables an optional field (git fetch_status,
// extra sysinfo fields, ...) never references it either way, so picking the
// most populated variant costs those themes nothing and gives every other
// theme's template more real data - ahead/behind counts, working-tree status,
// upstream icons - to render instead of zero values. This is what lets a
// single ~23KB fixture stand in for the 124 per-theme recordings it replaces -
// every segment key any bundled theme uses gets a plausible, richly populated
// value, without carrying 124 near-duplicate copies of the sparsest ones.
func buildMergedDataDocument(themesDir string) ([]byte, error) {
	themePaths, err := config.ThemeFiles(themesDir)
	if err != nil {
		return nil, err
	}

	if len(themePaths) == 0 {
		return nil, fmt.Errorf("no theme files found in %s", themesDir)
	}

	envValues := make(map[string][]json.RawMessage)
	segmentValues := make(map[string][]json.RawMessage)

	for _, themePath := range themePaths {
		env, segments, err := recordThemeSanitized(themePath)
		if err != nil {
			return nil, err
		}

		for key, value := range env {
			envValues[key] = append(envValues[key], value)
		}

		for key, value := range segments {
			segmentValues[key] = append(segmentValues[key], value)
		}

View on GitHub (pinned to 0976794618)

Solutions

  1. Check the path in the error message and point --themes at the directory that actually contains theme files (e.g. ../themes from src/)
  2. Verify with `ls <dir>/*.omp.*` (or your platform equivalent) that theme files with recognized extensions exist there
  3. Use an absolute path to avoid resolving a relative path against an unexpected working directory
  4. Confirm you did not pass a file instead of a directory

Example fix

// before
oh-my-posh config export data --themes ./themse --sanitize
// after
oh-my-posh config export data --themes ../themes --sanitize
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(themesDir)
if err != nil { return err }
if !info.IsDir() { return fmt.Errorf("%s is not a directory", themesDir) }
entries, _ := os.ReadDir(themesDir)
n := 0
for _, e := range entries {
    if !e.IsDir() { n++ }
}
if n == 0 { return fmt.Errorf("%s contains no theme files", themesDir) }

Try / catch

doc, err := buildMergedDataDocument(themesDir)
if err != nil {
    if strings.HasPrefix(err.Error(), "no theme files found") {
        return fmt.Errorf("check --themes path (got %q); expected a directory of theme files", themesDir)
    }
    return err
}

Prevention

When it happens

Trigger: Running `oh-my-posh config export data --themes <dir> --sanitize` where <dir> exists but contains no recognized theme files (empty dir, only non-theme files, wrong extension).

Common situations: Typo in the --themes path (pointing at a sibling empty directory); running from the wrong working directory with a relative path; themes directory contains only subdirectories or only files with unexpected extensions.

Related errors


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