invoke-ai/InvokeAI · error · InvalidWorkflowInputError
call_saved_workflow input '{input_name}' targets invalid chi
Error message
call_saved_workflow input '{input_name}' targets invalid child workflow inputs on '{node_id}' What it means
The matched node's 'inputs' member is not a mapping (dict), so the builder cannot insert the dynamic input value. The saved workflow's node data is malformed even though the node type and field validated.
Source
Thrown at invokeai/app/services/shared/workflow_graph_builder.py:158
)
if matching_node is None:
raise InvalidWorkflowInputError(
f"call_saved_workflow input '{input_name}' targets missing child workflow node '{node_id}'"
)
matching_node_data = matching_node["data"]
node_type = matching_node_data.get("type")
if not isinstance(node_type, str):
raise InvalidWorkflowInputError(
f"call_saved_workflow input '{input_name}' targets missing child workflow node '{node_id}'"
)
invocation_class = InvocationRegistry.get_invocation_for_type(node_type)
if invocation_class is None or field_name not in invocation_class.model_fields:
raise InvalidWorkflowInputError(
f"call_saved_workflow input '{input_name}' targets missing child workflow field '{field_name}'"
)
inputs = matching_node_data.setdefault("inputs", {})
if not _is_mapping(inputs):
raise InvalidWorkflowInputError(
f"call_saved_workflow input '{input_name}' targets invalid child workflow inputs on '{node_id}'"
)
inputs[field_name] = {"value": value}
def apply_workflow_inputs_to_graph(
graph: Graph, workflow: Mapping[str, Any], workflow_inputs: Mapping[str, Any]
) -> None:
if not workflow_inputs:
return
mutable_workflow = dict(workflow)
apply_workflow_inputs_to_workflow(mutable_workflow, workflow_inputs)
for input_name, value in workflow_inputs.items():
node_id, field_name = parse_call_saved_workflow_dynamic_input(input_name)
node = graph.nodes.get(node_id)
if node is None:
continueView on GitHub (pinned to 0b6a024f2f)
Solutions
- Fix the node's 'inputs' to be a dict keyed by field name (re-export from the editor).
- Re-save the workflow via the UI so the SDK serializes inputs correctly.
- Validate the workflow document (inputs mapping per node) before calling apply_workflow_inputs_to_workflow.
Example fix
// before
"inputs": ["prompt"]
// after
"inputs": {"prompt": {"value": "a cat"}} Defensive patterns
Strategy: type-guard
Validate before calling
def node_inputs_are_mapping(workflow: dict, node_id: str) -> bool:
node = next((n for n in workflow.get("nodes", []) if isinstance(n, dict) and n.get("id") == node_id), None)
return isinstance(node, dict) and isinstance(node.get("data", {}).get("inputs"), dict) Type guard
def has_mapping_inputs(node: dict) -> bool:
data = node.get("data") if isinstance(node, dict) else None
return isinstance(data, dict) and isinstance(data.get("inputs"), dict) Try / catch
try:
apply_workflow_inputs_to_workflow(workflow, workflow_inputs)
except InvalidWorkflowInputError as e:
if "invalid child workflow inputs" in str(e):
log.error("node inputs malformed in saved workflow: %s", e)
raise ValueError("Fix or re-export the workflow; node inputs must be a dict") from e
raise Prevention
- Only pass workflows deserialized through the official workflow schema, not raw JSON.
- Never hand-edit node 'inputs' structures; use the editor.
- Sanity-check each node's inputs type before programmatic graph manipulation.
When it happens
Trigger: apply_workflow_inputs_to_workflow: matching_node_data.setdefault("inputs", {}) returns a value for which _is_mapping(inputs) is False.
Common situations: Hand-edited workflow JSON where 'inputs' is a list or string; exports from other tools using a different inputs representation; truncated or programmatically corrupted workflow documents.
Related errors
- call_saved_workflow input '{input_name}' targets missing chi
- A saved workflow must be selected before executing call_save
- The selected saved workflow '${self.workflow_id}' could not
- Workflow return key must not be empty.
- Duplicate workflow return key '{key}'.
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/986f0a92d8727dc0.
Report an issue: GitHub.