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

  1. Fix the saved workflow so 'nodes' is a list of node objects (re-export from the workflow editor).
  2. Re-save the workflow through the UI/API instead of hand-editing JSON.
  3. 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

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


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/25433e33a6e266d8. Report an issue: GitHub.