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
- Check the config file and add or correct the `orchestration_templates.<name>` entry
- Copy the exact template name (case- and whitespace-sensitive) from config into the call/run argument
- List available templates by dumping the loaded config to confirm what exists
- 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
- Keep template names in a shared constant/enum instead of free strings
- Validate template references at config-load time, not at resolve time
- Copy template names exactly (case- and whitespace-sensitive) from config
- When config files are environment-specific, assert required templates exist at startup
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
- agent profile inheritance cycle
- An install config path is required
- application config exceeds local size limit
- Asset request_id/modality does not match the bundle
- at least one genre spec is required
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)