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

  1. Use one of the exact names: weekly_status, sprint_review, risk_register, milestone_report
  2. Check underscore spelling — hyphenated variants are rejected
  3. 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

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


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/c15f2e3902529905. Report an issue: GitHub.