{"record":{"id":"1ac3ddbcc1f840b0","repo":"affaan-m/ECC","slug":"missing-orchestration-template-variable-s","errorCode":null,"errorMessage":"missing orchestration template variable(s): {}","messagePattern":"missing orchestration template variable\\(s\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ecc2/src/config/mod.rs","lineNumber":878,"sourceCode":"    let mut missing = Vec::new();\n    let rendered = placeholder.replace_all(value, |captures: &regex::Captures<'_>| {\n        let key = captures\n            .get(1)\n            .map(|capture| capture.as_str())\n            .unwrap_or_default();\n        match vars.get(key) {\n            Some(value) => value.to_string(),\n            None => {\n                missing.push(key.to_string());\n                String::new()\n            }\n        }\n    });\n\n    if !missing.is_empty() {\n        missing.sort();\n        missing.dedup();\n        anyhow::bail!(\n            \"missing orchestration template variable(s): {}\",\n            missing.join(\", \")\n        );\n    }\n\n    Ok(rendered.into_owned())\n}\n\nimpl BudgetAlertThresholds {\n    pub fn sanitized(self) -> Self {\n        let values = [self.advisory, self.warning, self.critical];\n        let valid = values.into_iter().all(f64::is_finite)\n            && self.advisory > 0.0\n            && self.advisory < self.warning\n            && self.warning < self.critical\n            && self.critical < 1.0;\n\n        if valid {","sourceCodeStart":860,"sourceCodeEnd":896,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/config/mod.rs#L860-L896","documentation":"Runtime error from the template interpolation routine in ecc2/src/config/mod.rs. As each ${key} placeholder is rendered, any key missing from the `vars` map is appended to a `missing` list and rendered as empty. After rendering, if `missing` is non-empty, it is sorted, de-duplicated, and the method bails with \"missing orchestration template variable(s): {}\" joined by ', '. The message lists every required variable the caller did not supply.","triggerScenarios":"Calling resolve_orchestration_template (or its interpolation helper) when the template body or step fields reference ${VAR} placeholders that are absent from the supplied vars BTreeMap. The template is found and has steps, but the variable contract is unmet.","commonSituations":"A required --var was not passed on the CLI; the variable name in the template does not match the supplied key (typo, casing); the env-var source for a variable was not set so it never entered vars; a template was extended with new placeholders but the caller was not updated.","solutions":["Provide every variable named in the message, matching casing exactly.","Diff the template's ${...} placeholders against the vars you are passing.","If a variable is optional, give it a default in the template or omit the placeholder.","Generate vars from a single source of truth (env, file) to avoid drift."],"exampleFix":"# before\ntemplate = \"deploy ${env} ${region}\"\nvars = { env = \"prod\" }   # region missing\n\n# after\ntemplate = \"deploy ${env} ${region}\"\nvars = { env = \"prod\", region = \"us-east-1\" }","handlingStrategy":"validation","validationCode":"// Extract ${...} placeholders and confirm vars supplies all of them.\nuse regex::Regex;\nfn missing_vars(template: &str, vars: &BTreeMap<String, String>) -> Vec<String> {\n    let re = Regex::new(r\"\\$\\{([A-Za-z0-9_]+)\\}\").unwrap();\n    let mut required: HashSet<String> = re.captures_iter(template)\n        .map(|c| c[1].to_string()).collect();\n    for k in vars.keys() { required.remove(k); }\n    required.into_iter().collect()\n}","typeGuard":"fn has_all_vars(template: &str, vars: &BTreeMap<String, String>) -> bool {\n    missing_vars(template, vars).is_empty()\n}","tryCatchPattern":"let resolved = cfg.resolve_orchestration_template(name, &vars).map_err(|e| {\n    if e.to_string().contains(\"missing orchestration template variable\") {\n        anyhow::anyhow!(\"{e}; pass each as --var KEY=VALUE\")\n    } else {\n        e\n    }\n})?;","preventionTips":["Document required variables per template next to its definition.","Generate vars from a single source (env, file) to avoid drift.","Diff placeholders against supplied vars in a preflight check.","Give optional variables explicit defaults in the template."],"tags":["rust","config","templating","validation"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}