{"record":{"id":"c15f2e3902529905","repo":"zeroclaw-labs/zeroclaw","slug":"unsupported-template","errorCode":null,"errorMessage":"unsupported template: {}","messagePattern":"unsupported template: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/report_templates.rs","lineNumber":485,"sourceCode":"        format: ReportFormat::Markdown,\n    }\n}\n\n/// High-level template rendering function.\n/// Returns the rendered template as a string or an error if the template\n/// or language is not supported.\n#[allow(clippy::implicit_hasher)]\npub fn render_template(\n    template_name: &str,\n    language: &str,\n    vars: &HashMap<String, String>,\n) -> anyhow::Result<String> {\n    let tpl = match template_name {\n        \"weekly_status\" => weekly_status_template(language),\n        \"sprint_review\" => sprint_review_template(language),\n        \"risk_register\" => risk_register_template(language),\n        \"milestone_report\" => milestone_report_template(language),\n        _ => anyhow::bail!(\"unsupported template: {}\", template_name),\n    };\n    Ok(tpl.render(vars))\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn weekly_status_renders_with_variables() {\n        let tpl = weekly_status_template(\"en\");\n        let mut vars = HashMap::new();\n        vars.insert(\"project_name\".into(), \"ZeroClaw\".into());\n        vars.insert(\"period\".into(), \"2026-W10\".into());\n        vars.insert(\"completed\".into(), \"- Task A\\n- Task B\".into());\n        vars.insert(\"in_progress\".into(), \"- Task C\".into());\n        vars.insert(\"blocked\".into(), \"None\".into());\n        vars.insert(\"next_steps\".into(), \"- Task D\".into());","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/report_templates.rs#L467-L503","documentation":"render_template maps a template_name to one of four built-in, localized templates (weekly_status, sprint_review, risk_register, milestone_report) and then renders it with the supplied vars. Any other name reaches the bail arm and is rejected before rendering.","triggerScenarios":"Passing template_name values like \"daily_status\", \"weekly-status\", \"incident_report\", or a path like \"templates/weekly.txt\".","commonSituations":"Callers assuming arbitrary user-supplied templates are supported; naming drift after renaming a template in code but not in callers; hyphen-vs-underscore confusion.","solutions":["Use one of the exact names: weekly_status, sprint_review, risk_register, milestone_report","Check underscore spelling — hyphenated variants are rejected","If a new template is genuinely needed, add a match arm plus template function in report_templates.rs rather than passing an unsupported name"],"exampleFix":"// before\n{\"template\":\"weekly-status\",\"vars\":{...}}\n// after\n{\"template\":\"weekly_status\",\"vars\":{...}}","handlingStrategy":"validation","validationCode":"const TEMPLATES: &[&str] = &[\"weekly_status\",\"sprint_review\",\"risk_register\",\"milestone_report\"];\nif !TEMPLATES.contains(&name.as_str()) { /* reject before calling the tool */ }","typeGuard":"fn is_supported_template(n: &str) -> bool {\n    [\"weekly_status\",\"sprint_review\",\"risk_register\",\"milestone_report\"].contains(&n)\n}","tryCatchPattern":"Err(e) if e.to_string().starts_with(\"unsupported template\") => {\n    // offer the caller the four valid names as a corrective prompt\n}","preventionTips":["Expose template names as an enum or constant list in calling code","Keep the list in sync when adding templates (single source of truth in report_templates.rs)","Normalize hyphens to underscores in user input before validation"],"tags":["template","report","rendering","validation"],"backgroundTag":"unknown-template-name","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}