{"record":{"id":"e4356887cb50d033","repo":"helix-editor/helix","slug":"file-not-found-for","errorCode":null,"errorMessage":"File not found for: {}","messagePattern":"File not found for: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"helix-view/src/theme.rs","lineNumber":247,"sourceCode":"            .iter()\n            .find_map(|dir| {\n                let path = dir.join(&filename);\n                if !path.exists() {\n                    None\n                } else if visited_paths.contains(&path) {\n                    // Avoiding cycle, continuing to look in lower priority directories\n                    cycle_found = true;\n                    None\n                } else {\n                    visited_paths.insert(path.clone());\n                    Some(path)\n                }\n            })\n            .ok_or_else(|| {\n                if cycle_found {\n                    anyhow!(\"Cycle found in inheriting: {}\", name)\n                } else {\n                    anyhow!(\"File not found for: {}\", name)\n                }\n            })\n    }\n\n    pub fn default_theme(&self, true_color: bool) -> Theme {\n        if true_color {\n            self.default()\n        } else {\n            self.base16_default()\n        }\n    }\n\n    /// Returns the default theme\n    pub fn default(&self) -> Theme {\n        DEFAULT_THEME.clone()\n    }\n\n    /// Returns the alternative 16-color default theme","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/helix-editor/helix/blob/079a789e8cb08ead67f19e1971a1b7438b37354b/helix-view/src/theme.rs#L229-L265","documentation":"While resolving a theme (or an 'inherits' parent), Helix's Loader searches every configured themes directory in priority order for <name>.toml. If no directory contains that file — and the name is not one of the two built-ins 'default' / 'base16_default', which are served from embedded data — path() returns None for every directory and the loader raises 'File not found for: {name}'. The name is matched exactly (case-sensitive) against the file stem, and the file must live inside a directory named themes/ with a .toml extension.","triggerScenarios":"Calling Loader::load(\"nope\") when no themes/nope.toml exists in any theme dir; setting theme = \"Monokai Pro\" in config.toml (spaces/case don't match monokai_pro.toml); a theme file with inherits = \"solarized\" when only solarized-dark.toml exists; placing the file at ~/.config/helix/mytheme.toml instead of ~/.config/helix/themes/mytheme.toml; naming it mytheme.txt or mytheme.toml.toml so the stem mismatch fails lookup.","commonSituations":"Typos or wrong casing in the theme= setting of config.toml; referencing a theme that was renamed or removed in a newer Helix release; themes distributed as plugins that the user forgot to install; an inherits key naming a theme only present on another machine; file saved with a hidden double extension by editors that append .toml again.","solutions":["Confirm the exact file: run ls ~/.config/helix/themes/ (and the runtime themes/ dir) and copy the file stem verbatim — e.g. theme = \"monokai_pro_spectrum\", not \"MonokaiPro Spectrum\".","If the file is missing, move it into a themes/ subdirectory of the user config dir: ~/.config/helix/themes/<name>.toml (extension must be exactly .toml).","For a broken inherits key, point it at a theme that exists, or at the always-available built-ins: inherits = \"default\" or inherits = \"base16_default\" (these are matched specially and never need a file).","If the theme comes from a collection you meant to install, fetch it into the user themes directory (e.g. git clone the theme repo into ~/.config/helix/themes).","As a library consumer, pre-check existence (see defense section) so a missing theme falls back to default_theme() instead of propagating the error."],"exampleFix":"# before — ~/.config/helix/config.toml\ntheme = \"Monokai Pro\"\n\n# after (file is ~/.config/helix/themes/monokai_pro.toml)\ntheme = \"monokai_pro\"","handlingStrategy":"validation","validationCode":"// Check resolvability before Loader::load using the same dirs\n// you passed to Loader::new (highest priority first).\nfn theme_file_exists(dirs: &[PathBuf], name: &str) -> bool {\n    if name == \"default\" || name == \"base16_default\" {\n        return true; // embedded built-ins, no file needed\n    }\n    dirs.iter()\n        .map(|d| d.join(\"themes\").join(format!(\"{name}.toml\")))\n        .any(|p| p.exists())\n}\n\nlet theme_name = config.choose(mode);\nif !theme_file_exists(&dirs, theme_name) {\n    // fall back instead of letting Loader::load fail\n    return Ok(loader.default_theme(true_color));\n}","typeGuard":"fn is_loadable_theme(dirs: &[PathBuf], name: &str) -> bool {\n    theme_file_exists(dirs, name)\n}","tryCatchPattern":"// anyhow errors are untyped here, so match on the message prefix:\nmatch loader.load(theme_name) {\n    Ok(theme) => theme,\n    Err(err) if err.to_string().starts_with(\"File not found for\") => {\n        log::warn!(\"theme '{theme_name}' not installed, using default\");\n        loader.default_theme(true_color)\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Copy theme names from the actual file listing (ls ~/.config/helix/themes/), never from screenshots or docs — stems are matched case-sensitively with underscores, not spaces.","Custom themes go in the themes/ subdirectory of the config dir and must end in exactly .toml; beware editors that save file.toml.toml.","For inherits, prefer the always-present built-ins (\"default\", \"base16_default\") as roots of your chain.","After upgrading Helix, re-check theme = in config.toml against the shipped theme list (:theme followed by Tab completes available names).","When loading user-specified theme names programmatically, always validate existence first and keep default_theme() as the fallback path."],"tags":["helix","theme","toml","config","file-not-found","typo"],"backgroundTag":null,"analyzedSha":"079a789e8cb08ead67f19e1971a1b7438b37354b","analyzedAt":"2026-08-16T09:09:59.668Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}