JanDeDobbeleer/oh-my-posh · error

failed to record theme %s: %w

Error message

failed to record theme %s: %w

What it means

recordThemeSanitized renders a theme's segments against the real environment via render.Config (seeding writers from any --data file). If render.Config returns an error, it is wrapped as "failed to record theme <path>: <reason>". The cause is whatever went wrong during rendering — a failing segment, environment query error, or flag application problem.

Source

Thrown at src/cli/config_export_data.go:223

// exactly as the single-config path above does, then returns its sanitized env
// and segment maps for merging. Each call gets its own fresh template cache
// (resetTemplateCache=true, below, drives render.Config's own
// template.ResetCache before template.Init) so one theme's Var/Maps never leak
// into the next theme's render, the same isolation prompt/golden_test.go's
// renderTheme relies on between themes.
func recordThemeSanitized(themePath string) (env, segments map[string]json.RawMessage, err error) {
	cfg := config.Load(themePath)
	if cfg.Source == "" {
		return nil, nil, fmt.Errorf("failed to parse theme %s", themePath)
	}

	// --data seeds the writers with a fixture's own values before they render, so re-recording an
	// existing file keeps what it was curated with and only adds what the format has since gained.
	// Without it every theme would record whatever this machine happens to look like.
	if _, err := render.Config(cfg, 120, true, func(flags *runtime.Flags) error {
		return applyDataFile(flags, func(string) bool { return false })
	}); err != nil {
		return nil, nil, fmt.Errorf("failed to record theme %s: %w", themePath, err)
	}

	doc, err := buildDataDocument(cfg)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to record theme %s: %w", themePath, err)
	}

	sanitized, err := sanitizeDataDocument(doc, cfg)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to sanitize theme %s: %w", themePath, err)
	}

	var root map[string]json.RawMessage
	if err := json.Unmarshal(sanitized, &root); err != nil {
		return nil, nil, fmt.Errorf("failed to parse recorded theme %s: %w", themePath, err)
	}

	if raw, ok := root[config.DataEnvKey]; ok {

View on GitHub (pinned to 0976794618)

Solutions

  1. Inspect the wrapped cause to find which segment or step failed
  2. Rerun without --data (or with a freshly recorded fixture) to rule out stale seed data
  3. Test the failing theme alone via `oh-my-posh config export data --config <theme>` to reproduce and narrow the cause
  4. Update oh-my-posh; if a bundled theme fails, report it with the wrapped error

Example fix

// before
oh-my-posh config export data --sanitize --themes ../themes --data old.data.json

// after (fresh recording, no seed)
oh-my-posh config export data --sanitize --themes ../themes
Defensive patterns

Strategy: try-catch

Try / catch

env, segments, err := recordThemeSanitized(themePath)
if err != nil {
	if strings.Contains(err.Error(), "failed to record theme") {
		// inspect the wrapped render cause
		log.Printf("theme render failed: %v", err)
		return err
	}
	return err
}

Prevention

When it happens

Trigger: Running `config export data --themes --sanitize` when render.Config fails for a theme — e.g. a segment errors hard during render, the seeded --data fixture is incompatible with the theme, or the runtime environment returns an error the engine surfaces.

Common situations: A theme uses a segment that crashes/errors on this machine (missing tool, bad credential); a stale --data fixture missing newly required keys; shell/terminal environment mis-detected during batch theme recording.

Related errors


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