{"record":{"id":"1df6a78d49ed1cf7","repo":"getzola/zola","slug":"theme-is-missing-a-templates-folder","errorCode":null,"errorMessage":"Theme `{}` is missing a templates folder","messagePattern":"Theme `(.+?)` is missing a templates folder","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"components/templates/src/lib.rs","lineNumber":135,"sourceCode":"    tera.set_fallback_prefixes(fallback_prefixes)?;\n\n    // Register filters/tests/functions from ZOLA_TERA\n    tera.register_from(&ZOLA_TERA);\n\n    // Add builtin templates\n    for (name, content) in BUILTIN_TEMPLATES {\n        templates.push((name.to_string(), content.to_string()));\n    }\n\n    // Validate theme exists if configured\n    let site_tpl_dir = path.join(\"templates\");\n    let theme_tpl_dir =\n        config.theme.as_ref().map(|t| path.join(\"themes\").join(t).join(\"templates\"));\n\n    if let Some(ref theme_dir) = theme_tpl_dir\n        && !theme_dir.exists()\n    {\n        bail!(\"Theme `{}` is missing a templates folder\", config.theme.as_ref().unwrap());\n    }\n\n    if !site_tpl_dir.exists() && theme_tpl_dir.is_none() {\n        bail!(\"Either a `templates/` folder or a theme is required\");\n    }\n\n    // Load theme templates first (lower priority)\n    if let Some(ref theme) = config.theme {\n        let pattern = format!(\n            \"{}/themes/{theme}/templates/**/*.{{html,xml,md,txt,json,ics}}\",\n            glob_base(path)\n        );\n        for (file_path, name) in tera::load_from_glob(&pattern)? {\n            // \"page.html\" → \"sample/templates/page.html\"\n            let name = format!(\"{theme}/templates/{name}\");\n            let content = fs::read_to_string(&file_path)\n                .with_context(|| format!(\"Failed to read '{}'\", file_path.display()))?;\n            templates.push((name, content));","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/getzola/zola/blob/61d30828217957120309db657950224edf9707e2/components/templates/src/lib.rs#L117-L153","documentation":"`load_tera` in components/templates validates the theme layout. When `config.theme` is set, it requires `themes/<theme>/templates/` to exist; if it does not, it bails naming the missing theme. Themes in Zola must ship a templates folder to be loadable.","triggerScenarios":"Setting `theme = \"name\"` in config.toml while `themes/name/templates/` does not exist — theme not installed/cloned, wrong theme name, or theme repo lacking a `templates` directory.","commonSituations":"Forgetting `git clone` of the theme into `themes/`; typo in the theme name in config.toml; using a theme version that restructured its directories; cloning the theme repo into a differently named folder.","solutions":["Clone or copy the theme so `themes/<theme>/templates/` exists","Verify the theme name in config.toml exactly matches the folder name in `themes/`","Check the theme repository actually contains a `templates` directory (update the theme if it moved)"],"exampleFix":"// before\n# config.toml: theme = \"hyde\"  (themes/hyde missing)\n// after\n$ git clone https://github.com/getzola/hyde themes/hyde\n# themes/hyde/templates/ now exists","handlingStrategy":"validation","validationCode":"if let Some(theme) = &config.theme {\n    assert!(Path::new(\"themes\").join(theme).join(\"templates\").is_dir(), \"theme '{theme}' missing templates/\");\n}","typeGuard":null,"tryCatchPattern":"match load_tera(base_path, &config) {\n    Ok(t) => use(t),\n    Err(e) if e.to_string().contains(\"is missing a templates folder\") => {\n        eprintln!(\"install the theme: git clone <theme-url> themes/<name>\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Clone the theme into themes/<exact-name>/ before setting `theme` in config.toml","Match the config `theme` value exactly to the folder name","Verify the downloaded theme contains a templates/ directory","Document theme setup in the project README/bootstrap script"],"tags":["rust","zola","themes","configuration"],"backgroundTag":"missing-templates-folder","analyzedSha":"61d30828217957120309db657950224edf9707e2","analyzedAt":"2026-09-03T14:39:09.727Z","contentChangedAt":"2026-09-03T14:39:09.727Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}