{"record":{"id":"5c84e808aceb0dbd","repo":"loco-rs/loco","slug":"failed-to-retrieve-file-stem","errorCode":null,"errorMessage":"Failed to retrieve file stem","messagePattern":"Failed to retrieve file stem","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"loco-new/src/generator/template.rs","lineNumber":114,"sourceCode":"        let mut tera_instance = Tera::default();\n        self.register_filters(&mut tera_instance);\n\n        let mut context = Context::new();\n        context.insert(\"settings\", &settings);\n\n        let rendered_output = tera_instance.render_str(template_content, &context)?;\n\n        Ok(rendered_output)\n    }\n\n    /// Removes the \".t\" extension from a template file path, if present.\n    ///\n    /// # Errors\n    /// if the given path is not contains template extension\n    pub fn strip_template_extension(&self, path: &Path) -> std::io::Result<PathBuf> {\n        path.file_stem().map_or_else(\n            || {\n                Err(std::io::Error::new(\n                    std::io::ErrorKind::InvalidInput,\n                    \"Failed to retrieve file stem\",\n                ))\n            },\n            |stem| {\n                let mut path_without_extension = path.to_path_buf();\n                path_without_extension.set_file_name(stem);\n                if let Some(parent_dir) = path.parent() {\n                    path_without_extension = parent_dir.join(stem.to_string_lossy().to_string());\n                }\n                Ok(path_without_extension)\n            },\n        )\n    }\n}\n\n#[cfg(test)]\nmod tests {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/loco-rs/loco/blob/23639d1e360dbc618073642b507d6f8664adbaff/loco-new/src/generator/template.rs#L96-L132","documentation":"An `io::Error` with `InvalidInput` returned by `strip_template_extension` when the given path has no file stem (no final path component usable as a stem). `Path::file_stem()` returns `None` for paths ending in `..`, empty paths, or root-only paths, and this maps that to an error.","triggerScenarios":"Calling `strip_template_extension` on a path without a template extension or with no filename component (e.g. `Path::new(\"\"), Path::new(\".\"), Path::new(\"/\"), Path::new(\"foo/..\")`).","commonSituations":"Programmatic path construction that produced an empty or dotted path before rendering templates; wrong glob/extraction producing paths with no stem.","solutions":["Ensure the path passed in has a real file name with a template extension (e.g. `file.t` or `file.html.t`)","Validate the path with `path.file_stem().is_some()` before calling","Guard the caller to skip non-file paths like directories or `.`/`..` components"],"exampleFix":"// before\ngenerator.strip_template_extension(Path::new(\"\"))?;\n// after\nlet p = Path::new(\"templates/user.html.t\");\nassert!(p.file_stem().is_some());\ngenerator.strip_template_extension(p)?;","handlingStrategy":"type-guard","validationCode":"fn has_stem(p: &Path) -> bool { p.file_stem().is_some() && p.extension().is_some() }","typeGuard":"fn is_strippable(p: &Path) -> bool {\n    p.file_stem().is_some() && p.to_string_lossy().ends_with(\".t\")\n}","tryCatchPattern":"match generator.strip_template_extension(&path) {\n    Ok(stem) => use(stem),\n    Err(e) => tracing::warn!(\"skipping non-template path: {e}\"),\n}","preventionTips":["Only call strip_template_extension on real file paths discovered by a file walker","Skip directory or dot entries (., ..) before processing","Assert paths carry the template extension before stripping"],"tags":["filesystem","path","template","generator"],"backgroundTag":"null-argument","analyzedSha":"23639d1e360dbc618073642b507d6f8664adbaff","analyzedAt":"2026-09-12T01:47:20.769Z","contentChangedAt":"2026-09-12T01:47:20.769Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}