invoke-ai/InvokeAI · error · InvalidWorkflowInputError
call_saved_workflow input '{input_name}' targets missing chi
Error message
call_saved_workflow input '{input_name}' targets missing child workflow node '{node_id}' What it means
The workflow's 'nodes' entry could not be read as a list (or is absent in the expected shape), so a call_saved_workflow input cannot target any node. The builder raises because the saved workflow document is structurally malformed for node lookup.
Source
Thrown at invokeai/app/services/shared/workflow_graph_builder.py:127
return fallback_inputs
def apply_workflow_inputs_to_workflow(workflow: MutableMapping[str, Any], workflow_inputs: Mapping[str, Any]) -> None:
if not workflow_inputs:
return
allowed_inputs = get_exposed_workflow_input_names(workflow)
for input_name, value in workflow_inputs.items():
if input_name not in allowed_inputs:
raise InvalidWorkflowInputError(
f"call_saved_workflow input '{input_name}' is not exposed by the selected workflow"
)
node_id, field_name = parse_call_saved_workflow_dynamic_input(input_name)
workflow_nodes = workflow.get("nodes", [])
if not isinstance(workflow_nodes, list):
raise InvalidWorkflowInputError(
f"call_saved_workflow input '{input_name}' targets missing child workflow node '{node_id}'"
)
matching_node = next(
(
node
for node in workflow_nodes
if _is_mapping(node)
and _is_mapping(node.get("data"))
and node.get("id") == node_id
and node["data"].get("id") == node_id
),
None,
)
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"]View on GitHub (pinned to 0b6a024f2f)
Solutions
- Fix the saved workflow so 'nodes' is a list of node objects (re-export from the workflow editor).
- Re-save the workflow through the UI/API instead of hand-editing JSON.
- Validate the workflow document shape before passing it to the builder.
Example fix
// before (corrupted export)
workflow = {"nodes": {"13": {...}}}
// after
workflow = {"nodes": [{"id": "13", "data": {...}}]} Defensive patterns
Strategy: type-guard
Validate before calling
def workflow_nodes_are_list(workflow: dict) -> bool:
nodes = workflow.get("nodes", [])
return isinstance(nodes, list)
# call before apply_workflow_inputs_to_workflow Type guard
def has_valid_nodes(workflow: dict) -> bool:
nodes = workflow.get("nodes")
return isinstance(nodes, list) and all(isinstance(n, dict) for n in nodes) Try / catch
try:
apply_workflow_inputs_to_workflow(workflow, workflow_inputs)
except InvalidWorkflowInputError as e:
if "missing child workflow node" in str(e):
log.error("Malformed workflow document (nodes not a list): %s", e)
raise ValueError("Re-export the workflow from the editor") from e
raise Prevention
- Never hand-edit saved workflow JSON; re-export from the workflow editor.
- Validate workflow documents against the workflow schema before use.
- Only pass workflows loaded through the official workflow records API.
When it happens
Trigger: apply_workflow_inputs_to_workflow parses input name to (node_id, field_name), then workflow.get("nodes", []) is not a list; raising before any node matching is attempted.
Common situations: Saved workflow JSON was hand-edited or corrupted so 'nodes' is an object/string; an older or foreign export format lacks a proper nodes array; programmatically constructed workflow dicts with wrong shape.
Related errors
- call_saved_workflow input '{input_name}' targets invalid 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/25433e33a6e266d8.
Report an issue: GitHub.