{"record":{"id":"02c0a43823eb4833","repo":"affaan-m/ECC","slug":"orchestration-template-name-has-no-steps","errorCode":null,"errorMessage":"orchestration template {name} has no steps","messagePattern":"orchestration template (.+?) has no steps","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ecc2/src/config/mod.rs","lineNumber":403,"sourceCode":"    }\n\n    pub fn harness_runner(&self, harness: &str) -> Option<&HarnessRunnerConfig> {\n        let key = harness.trim().to_ascii_lowercase();\n        self.harness_runners.get(&key)\n    }\n\n    pub fn resolve_orchestration_template(\n        &self,\n        name: &str,\n        vars: &BTreeMap<String, String>,\n    ) -> Result<ResolvedOrchestrationTemplate> {\n        let template = self\n            .orchestration_templates\n            .get(name)\n            .ok_or_else(|| anyhow::anyhow!(\"Unknown orchestration template: {name}\"))?;\n\n        if template.steps.is_empty() {\n            anyhow::bail!(\"orchestration template {name} has no steps\");\n        }\n\n        let description = interpolate_optional_string(template.description.as_deref(), vars)?;\n        let project = interpolate_optional_string(template.project.as_deref(), vars)?;\n        let task_group = interpolate_optional_string(template.task_group.as_deref(), vars)?;\n        let default_agent = interpolate_optional_string(template.agent.as_deref(), vars)?;\n        let default_profile = interpolate_optional_string(template.profile.as_deref(), vars)?;\n        if let Some(profile_name) = default_profile.as_deref() {\n            self.resolve_agent_profile(profile_name)?;\n        }\n\n        let mut steps = Vec::with_capacity(template.steps.len());\n        for (index, step) in template.steps.iter().enumerate() {\n            let task = interpolate_required_string(&step.task, vars).with_context(|| {\n                format!(\n                    \"resolve task for orchestration template {name} step {}\",\n                    index + 1\n                )","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/config/mod.rs#L385-L421","documentation":"This error is thrown when resolving an orchestration template by name: the template exists in the configuration, but its `steps` list is empty. The library refuses to instantiate a template that would produce zero steps, since an orchestration with no steps is meaningless and would silently do nothing. It is a defensive configuration sanity check performed after template lookup succeeds.","triggerScenarios":"Calling the template-resolution code (e.g. resolving/rendering an orchestration template by name) where the named template is present in `orchestration_templates` but its `steps` field is an empty array or was never populated.","commonSituations":"A TOML/JSON config file declares an orchestration template section with description/project/agent fields but omits the steps list; a migration or hand-edit stripped the steps; a template was copy-pasted as a stub and never filled in; a programmatic config builder created the template struct without pushing steps.","solutions":["Add at least one step to the `steps` array of the named orchestration template in your config file.","Check the template name in your invocation — you may be referencing a stub template instead of the fully populated one.","Validate the config before use: iterate all orchestration_templates and fail fast on any with empty steps.","If the template is intentionally empty, remove it from config rather than leaving an empty definition."],"exampleFix":"# before (config)\n[orchestration_templates.deploy]\ndescription = \"Deploy pipeline\"\nsteps = []\n\n# after\n[orchestration_templates.deploy]\ndescription = \"Deploy pipeline\"\nsteps = [\n  { name = \"build\", agent = \"builder\" },\n  { name = \"verify\", agent = \"code-reviewer\" }\n]","handlingStrategy":"validation","validationCode":"for (name, tpl) in &config.orchestration_templates {\n    if tpl.steps.is_empty() {\n        return Err(anyhow!(\"template '{name}' has no steps\"));\n    }\n}","typeGuard":"fn has_steps(tpl: &OrchestrationTemplate) -> bool { !tpl.steps.is_empty() }","tryCatchPattern":"match resolver.resolve_template(name, &vars) {\n    Ok(t) => t,\n    Err(e) if e.to_string().contains(\"has no steps\") => {\n        eprintln!(\"Template '{name}' is empty; check config\");\n        Default::default()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never commit templates with empty steps arrays; lint the config file in CI.","Give every new template a placeholder step immediately after creating it.","Keep template definitions in one reviewed config file rather than scattering edits.","Unit-test resolution of every declared template at startup."],"tags":["config","orchestration","validation","rust"],"backgroundTag":"empty-required-field","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}