{"record":{"id":"f1e73b26982794b2","repo":"JanDeDobbeleer/oh-my-posh","slug":"failed-to-parse-theme-s","errorCode":null,"errorMessage":"failed to parse theme %s","messagePattern":"failed to parse theme (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/config_export_data.go","lineNumber":214,"sourceCode":"\tdataCmd.Flags().StringVar(&dataPath, \"data\", \"\",\n\t\t\"path to a template data file to seed the recording with, instead of the live environment\")\n\tdataCmd.Flags().StringVar(&themesDir, \"themes\", \"\",\n\t\t\"record every theme in this directory and merge them into one sanitized fixture, ignoring --config (requires --sanitize)\")\n\n\texportCmd.AddCommand(dataCmd)\n}\n\n// recordThemeSanitized runs one theme's segments against the real environment,\n// exactly as the single-config path above does, then returns its sanitized env\n// and segment maps for merging. Each call gets its own fresh template cache\n// (resetTemplateCache=true, below, drives render.Config's own\n// template.ResetCache before template.Init) so one theme's Var/Maps never leak\n// into the next theme's render, the same isolation prompt/golden_test.go's\n// renderTheme relies on between themes.\nfunc recordThemeSanitized(themePath string) (env, segments map[string]json.RawMessage, err error) {\n\tcfg := config.Load(themePath)\n\tif cfg.Source == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse theme %s\", themePath)\n\t}\n\n\t// --data seeds the writers with a fixture's own values before they render, so re-recording an\n\t// existing file keeps what it was curated with and only adds what the format has since gained.\n\t// Without it every theme would record whatever this machine happens to look like.\n\tif _, err := render.Config(cfg, 120, true, func(flags *runtime.Flags) error {\n\t\treturn applyDataFile(flags, func(string) bool { return false })\n\t}); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to record theme %s: %w\", themePath, err)\n\t}\n\n\tdoc, err := buildDataDocument(cfg)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to record theme %s: %w\", themePath, err)\n\t}\n\n\tsanitized, err := sanitizeDataDocument(doc, cfg)\n\tif err != nil {","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/cli/config_export_data.go#L196-L232","documentation":"recordThemeSanitized (used by `config export data --themes --sanitize`) loads a theme file with config.Load. If the resulting config has an empty Source — the loader failed to read or parse the file — it returns \"failed to parse theme <path>\". It means the theme file at that path could not be loaded as a valid oh-my-posh config.","triggerScenarios":"Running the --themes merge over a directory where one of the discovered files is unreadable, empty, or not a valid TOML/JSON/YAML config, so config.Load yields cfg.Source == \"\".","commonSituations":"Pointing --themes at a directory containing stray non-config files (README, partial JSON, editor backups like theme.json~); a truncated download; wrong file extension; permission errors on the file.","solutions":["Open the named theme file and fix or remove it from the directory","Validate the file parses (run `oh-my-posh config migrate --config <file>` or print with it) to see the underlying syntax error","Check file permissions and that the file is not empty","Point --themes at a directory containing only valid theme configs (e.g. the bundled themes/ folder)"],"exampleFix":"// before\n--themes ../my-mixed-dir   # contains theme.json.bak\n\n// after\n--themes ../themes          # only valid *.omp.json files","handlingStrategy":"validation","validationCode":"// Go: verify the theme loads before batch-recording\nvar cfg = config.Load(path)\nif cfg.Source == \"\" {\n\treturn fmt.Errorf(\"theme %s is not a valid config\", path)\n}","typeGuard":"func themeLoads(path string) bool {\n\treturn config.Load(path).Source != \"\"\n}","tryCatchPattern":"env, segments, err := recordThemeSanitized(themePath)\nif err != nil {\n\tif strings.Contains(err.Error(), \"failed to parse theme\") {\n\t\tfmt.Fprintf(os.Stderr, \"skipping invalid theme: %v\\n\", err)\n\t\treturn nil // or fail fast, per policy\n\t}\n\treturn err\n}","preventionTips":["Point --themes at directories containing only valid theme configs","Validate each theme with a quick `oh-my-posh print primary --config <file>` before batch runs","Exclude editor backups and partial files (glob *.omp.json only)","Check file permissions before recording across user directories"],"tags":["config","parsing","themes","export"],"backgroundTag":"config-parse-failed","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}