{"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":"exception","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/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/config/mod.rs#L385-L421","documentation":"Runtime error from Config::resolve_orchestration_template in ecc2/src/config/mod.rs. Immediately after locating the template, the method checks template.steps.is_empty(); if the template exists but defines no steps, it bails with \"orchestration template {name} has no steps\". The template was found, but it is unusable because there is nothing to run.","triggerScenarios":"Calling resolve_orchestration_template on a template whose `steps` array is empty or omitted in the config. The lookup succeeds but the steps guard fails.","commonSituations":"User added a template skeleton and forgot to populate steps; a YAML/TOML indentation error placed steps under the wrong key so the array parses as empty; the steps key is misspelled (e.g. step instead of steps); a refactor moved steps into a sub-table that the schema does not read.","solutions":["Open the config and confirm the template has a non-empty `steps` array at the correct nesting level.","Validate the config file against the schema and fix indentation / key-name errors.","If the template is intentionally a placeholder, remove its references until it has steps.","Re-run config validation/lint to catch malformed structures before runtime."],"exampleFix":"# before\n[[orchestration_templates]]\nname = \"deploy\"\n\n# after\n[[orchestration_templates]]\nname = \"deploy\"\nsteps = [\n  { agent = \"deployer\", task = \"push\" },\n]","handlingStrategy":"validation","validationCode":"// Validate the template's step count before resolving.\nif let Some(t) = cfg.template(name) {\n    if t.steps.is_empty() {\n        eprintln!(\"template {name} has no steps; refusing to resolve\");\n        return Ok(());\n    }\n}","typeGuard":"fn template_has_steps(cfg: &Config, name: &str) -> bool {\n    cfg.template(name).map(|t| !t.steps.is_empty()).unwrap_or(false)\n}","tryCatchPattern":"let resolved = cfg.resolve_orchestration_template(name, &vars).map_err(|e| {\n    if e.to_string().contains(\"has no steps\") {\n        anyhow::anyhow!(\"{e}; add at least one step to [[orchestration_templates]] name = {name:?}\")\n    } else {\n        e\n    }\n})?;","preventionTips":["Lint orchestration templates for non-empty steps in CI.","Use a schema validator that requires min_items=1 on steps.","Watch YAML/TOML indentation so steps land under the right table.","Add a config test that exercises each template."],"tags":["rust","config","validation","orchestration"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}