zeroclaw-labs/zeroclaw · error · anyhow::Error
unsupported template: {}
Error message
unsupported template: {} What it means
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.
Source
Thrown at crates/zeroclaw-tools/src/report_templates.rs:485
format: ReportFormat::Markdown,
}
}
/// High-level template rendering function.
/// Returns the rendered template as a string or an error if the template
/// or language is not supported.
#[allow(clippy::implicit_hasher)]
pub fn render_template(
template_name: &str,
language: &str,
vars: &HashMap<String, String>,
) -> anyhow::Result<String> {
let tpl = match template_name {
"weekly_status" => weekly_status_template(language),
"sprint_review" => sprint_review_template(language),
"risk_register" => risk_register_template(language),
"milestone_report" => milestone_report_template(language),
_ => anyhow::bail!("unsupported template: {}", template_name),
};
Ok(tpl.render(vars))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn weekly_status_renders_with_variables() {
let tpl = weekly_status_template("en");
let mut vars = HashMap::new();
vars.insert("project_name".into(), "ZeroClaw".into());
vars.insert("period".into(), "2026-W10".into());
vars.insert("completed".into(), "- Task A\n- Task B".into());
vars.insert("in_progress".into(), "- Task C".into());
vars.insert("blocked".into(), "None".into());
vars.insert("next_steps".into(), "- Task D".into());View on GitHub (pinned to 88bb9c8533)
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
Example fix
// before
{"template":"weekly-status","vars":{...}}
// after
{"template":"weekly_status","vars":{...}} Defensive patterns
Strategy: validation
Validate before calling
const TEMPLATES: &[&str] = &["weekly_status","sprint_review","risk_register","milestone_report"];
if !TEMPLATES.contains(&name.as_str()) { /* reject before calling the tool */ } Type guard
fn is_supported_template(n: &str) -> bool {
["weekly_status","sprint_review","risk_register","milestone_report"].contains(&n)
} Try / catch
Err(e) if e.to_string().starts_with("unsupported template") => {
// offer the caller the four valid names as a corrective prompt
} Prevention
- 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
When it happens
Trigger: Passing template_name values like "daily_status", "weekly-status", "incident_report", or a path like "templates/weekly.txt".
Common situations: Callers assuming arbitrary user-supplied templates are supported; naming drift after renaming a template in code but not in callers; hyphen-vs-underscore confusion.
Related errors
- modal custom_id exceeds Discord's 100-char limit; cannot ope
- slash command registration failed for '{name}' ({status}): {
- unknown git channel provider `{other}` (supported: github, g
- git channel `events` routing table ignores every event type;
- invalid forge HTTP method `{}` (expected GET/POST/PATCH/PUT/
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/c15f2e3902529905.
Report an issue: GitHub.