windmill-labs/windmill · error
Failed to parse inventory arg: {}
Error message
Failed to parse inventory arg: {} What it means
The inventory argument was found in args but its string value is not valid JSON; serde_json::from_str fails and the executor wraps the serde error with this message. Windmill stores inventories as JSON strings, so any non-JSON value passed as the inventory argument triggers this.
Source
Thrown at backend/windmill-worker/src/ansible_executor.rs:2260
for inventory in &r.inventories {
let content;
if let Some(resource_path) = &inventory.pinned_resource {
content = client
.get_resource_value_interpolated::<serde_json::Value>(
resource_path,
Some(job_id.to_string()),
)
.await?;
} else {
let o = args
.as_ref()
.and_then(|g| g.get(&inventory.name))
.ok_or(anyhow!(
"Specified inventory was missing in the script arguments"
))?;
content = serde_json::from_str(o.get())
.map_err(|e| anyhow!("Failed to parse inventory arg: {}", e))?;
if content == serde_json::value::Value::Null {
Err(anyhow!("The inventory argument was left empty. If you do not wish to specify an inventory for this script, remove the `inventory:` section from the yaml."))?;
}
}
let validated_path = write_file_at_user_defined_location(
job_dir,
&inventory.name,
content
.get("content")
.and_then(|v| v.as_str())
.ok_or(anyhow!(
"Invalid inventory resource, `content` field absent or invalid"
))?,
None,
)
.map_err(|e| anyhow!("Couldn't write inventory: {}", e))?;View on GitHub (pinned to e474e8803c)
Solutions
- Convert the inventory to JSON (JSON array-of-groups or object form) — e.g. `{"web": {"hosts": ["host1"]}}`.
- If you have INI/YAML inventory, keep it as the `content` of an inventory resource instead, or translate it to JSON.
- Validate the JSON with `jq .` before passing it.
- Check the interpolating step isn't injecting unquoted non-JSON text.
Example fix
// before (INI, invalid JSON)
--data '{"inv": "[web]\nhost1 ansible_host=10.0.0.1"}'
// after (JSON)
--data '{"inv": "{\"web\": {\"hosts\": [\"host1\"], \"vars\": {\"ansible_host\": \"10.0.0.1\"}}}"}' Defensive patterns
Strategy: validation
Validate before calling
try { JSON.parse(inventoryArg); } catch (e) { throw new Error('inventory arg must be valid JSON: ' + e.message); } Type guard
function isValidJsonInventory(s) {
if (typeof s !== 'string') return false;
try { const v = JSON.parse(s); return v !== null && typeof v === 'object'; } catch { return false; }
} Prevention
- Always pass inventories as JSON documents, never INI/YAML text.
- Validate with `jq .` or JSON.parse before running the script.
- Convert classic ansible inventories to JSON format once, store as a resource.
- Check template interpolation isn't injecting non-JSON text.
When it happens
Trigger: Passing the inventory argument as YAML, INI, or plain text (e.g. `[web]\nhost1 ansible_host=1.2.3.4`) instead of a JSON document, or passing a number/boolean rather than an object/string of JSON, in create_file_resources via handle_ansible_job.
Common situations: Users pasting classic INI inventory format into the arg; copy-pasting YAML inventory from ansible docs; a template interpolating non-JSON content; a flow upstream step emitting raw text.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse yaml: {}
- Invalid inventory definition
- YAML parse error: {}
- Expected an object (map) for the `ansible-galaxy collection
- Specified inventory was missing in the script arguments
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/2991771b1da2d4de.
Report an issue: GitHub.