{"record":{"id":"0940aedb02b042cb","repo":"windmill-labs/windmill","slug":"invalid-inventory-definition","errorCode":null,"errorMessage":"Invalid inventory definition","messagePattern":"Invalid inventory definition","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-yaml/src/lib.rs","lineNumber":376,"sourceCode":"                        .map(|s| s.to_string())\n                        .unwrap_or_else(|| {\n                            count += 1;\n                            if count == 0 {\n                                \"Additional inventories\".to_string()\n                            } else {\n                                format!(\"Additional inventories ({count})\")\n                            }\n                        });\n\n                    ret.push(PreexistingAnsibleInventory::PassedInArgs(\n                        InventoryFilenameListDefinition { options, name },\n                    ))\n                }\n            }\n        }\n        return Ok(ret);\n    }\n    return Err(anyhow!(\"Invalid inventory definition\"));\n}\n\nfn parse_inventories(inventory_yaml: &Yaml) -> anyhow::Result<Vec<AnsibleInventory>> {\n    if let Yaml::Array(arr) = inventory_yaml {\n        let mut ret = vec![];\n        for (i, inv) in arr.iter().enumerate() {\n            if let Yaml::Hash(inv) = inv {\n                let resource_type = inv\n                    .get(&Yaml::String(\"resource_type\".to_string()))\n                    .and_then(|v| v.as_str())\n                    .map(|s| s.to_string());\n\n                let windmill_path = inv\n                    .get(&Yaml::String(\"default\".to_string()))\n                    .and_then(|v| v.as_str())\n                    .map(|s| s.to_string());\n\n                let name = if i == 0 {","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-yaml/src/lib.rs#L358-L394","documentation":"parse_additional_inventories walks the `additional_inventories` value of the Ansible requirements YAML and returns Ok only if every entry matches the expected structure (inventory as array/hash with known keys). If the value never matches any accepted shape, the function falls through to this generic error.","triggerScenarios":"Calling parse_ansible_sig or parse_ansible_reqs with `additional_inventories:` in the YAML whose content is neither a valid list of inventory entries nor of an accepted type (e.g. a bare string or scalar instead of the expected array/hash).","commonSituations":"Writing `additional_inventories: prod` instead of a list of inventory objects, or nesting an inventory under an unrecognized key so no branch of the match accepts it.","solutions":["Ensure `additional_inventories` is an array of inventory definitions in the documented format.","Check each inventory entry uses only the recognized keys (name/path/host_list etc. as supported).","Validate the YAML structure against the AnsibleRequirements schema in the source."],"exampleFix":"# before\nadditional_inventories: prod\n# after\nadditional_inventories:\n  - name: prod\n    path: inventories/prod","handlingStrategy":"validation","validationCode":"fn valid_additional_inventories(v: &Yaml) -> bool {\n    matches!(v, Yaml::Array(items) if items.iter().all(|i| matches!(i, Yaml::Hash(_))))\n}","typeGuard":"fn is_inventory_array(v: &Yaml) -> bool { matches!(v, Yaml::Array(_)) }","tryCatchPattern":"match parse_ansible_reqs(content) {\n    Ok(r) => r,\n    Err(e) if e.to_string() == \"Invalid inventory definition\" => {\n        eprintln!(\"Fix additional_inventories structure: expected array of inventory objects\");\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Always provide additional_inventories as a list of mappings","Use only documented inventory keys","Validate structure against AnsibleRequirements schema in tests"],"tags":["yaml","ansible","inventory","schema-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}