affaan-m/ECC · error · anyhow::Error

Unknown orchestration template

Error message

Unknown orchestration template: {name}

What it means

The config layer's orchestration-template resolver looks up `name` in the configured `orchestration_templates` map and raises this error when the key is absent. It is a configuration lookup failure: the requested template was never defined (or was renamed/deleted) in the user's config.

Solutions

  1. Check the config file and add or correct the `orchestration_templates.<name>` entry
  2. Copy the exact template name (case- and whitespace-sensitive) from config into the call/run argument
  3. List available templates by dumping the loaded config to confirm what exists
  4. If config was recently migrated, restore the template definition from version control

Example fix

// before
run_template("reivew-fix")?; // typo
// after
let name = "review-fix";
anyhow::ensure!(
    config.orchestration_templates.contains_key(name),
    "template {name} missing; available: {:?}",
    config.orchestration_templates.keys().collect::<Vec<_>>()
);
run_template(name)?;
Defensive patterns

Strategy: validation

Validate before calling

if !config.orchestration_templates.contains_key(name) {
    anyhow::bail!(
        "template '{name}' not found; available: {:?}",
        config.orchestration_templates.keys().collect::<Vec<_>>()
    );
}

Try / catch

match config.resolve_orchestration_template(name, &vars) {
    Ok(t) => t,
    Err(e) if e.to_string().starts_with("Unknown orchestration template") => {
        eprintln!("check config key spelling for '{name}'; template definitions live in the config file");
        Err(e)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Resolving an orchestration template by name when the config file omits that template, the name is misspelled or differs in case, or the config was reloaded/reset and the definition dropped.

Common situations: Typo between the run command's --template argument and the config key; template renamed in a config refactor; environment-specific config files where only some define the template; whitespace in the name key.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/6ecf14d2284e378e. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/config/mod.rs:400

    pub fn resolve_agent_profile(&self, name: &str) -> Result<ResolvedAgentProfile> {
        let mut chain = Vec::new();
        self.resolve_agent_profile_inner(name, &mut chain)
    }

    pub fn harness_runner(&self, harness: &str) -> Option<&HarnessRunnerConfig> {
        let key = harness.trim().to_ascii_lowercase();
        self.harness_runners.get(&key)
    }

    pub fn resolve_orchestration_template(
        &self,
        name: &str,
        vars: &BTreeMap<String, String>,
    ) -> Result<ResolvedOrchestrationTemplate> {
        let template = self
            .orchestration_templates
            .get(name)
            .ok_or_else(|| anyhow::anyhow!("Unknown orchestration template: {name}"))?;

        if template.steps.is_empty() {
            anyhow::bail!("orchestration template {name} has no steps");
        }

        let description = interpolate_optional_string(template.description.as_deref(), vars)?;
        let project = interpolate_optional_string(template.project.as_deref(), vars)?;
        let task_group = interpolate_optional_string(template.task_group.as_deref(), vars)?;
        let default_agent = interpolate_optional_string(template.agent.as_deref(), vars)?;
        let default_profile = interpolate_optional_string(template.profile.as_deref(), vars)?;
        if let Some(profile_name) = default_profile.as_deref() {
            self.resolve_agent_profile(profile_name)?;
        }

        let mut steps = Vec::with_capacity(template.steps.len());
        for (index, step) in template.steps.iter().enumerate() {
            let task = interpolate_required_string(&step.task, vars).with_context(|| {
                format!(

View on GitHub (pinned to 8321021c54)