invoke-ai/InvokeAI · error · UnsupportedWorkflowNodeError

call_saved_workflow child workflow is malformed

Error message

call_saved_workflow child workflow is malformed

What it means

_build_child_graph_workflow filters a saved workflow before expanding a call_saved_workflow node into a batch of child sessions. It requires the workflow's 'nodes' and 'edges' members to both be lists; if either is missing or of the wrong JSON type it raises UnsupportedWorkflowNodeError('call_saved_workflow child workflow is malformed'), since the expansion cannot proceed on a structurally invalid workflow.

Source

Thrown at invokeai/app/services/session_processor/workflow_call_batch.py:141

        if source_node is None:
            return None

        if _is_invocation_node(source_node):
            return (source_id, source_handle)

        if _is_connector_node(source_node):
            return resolve(source_id)

        return None

    return resolve(connector_id)


def _build_child_graph_workflow(workflow: Mapping[str, Any], used_generator_node_ids: set[str]) -> dict[str, Any]:
    workflow_nodes = workflow.get("nodes", [])
    workflow_edges = workflow.get("edges", [])
    if not isinstance(workflow_nodes, list) or not isinstance(workflow_edges, list):
        raise UnsupportedWorkflowNodeError("call_saved_workflow child workflow is malformed")

    filtered_nodes = [
        node
        for node in workflow_nodes
        if not (
            _is_invocation_node(node)
            and (
                node["data"].get("type") in SUPPORTED_BATCH_TYPES
                or (isinstance(node.get("id"), str) and node["id"] in used_generator_node_ids)
            )
        )
    ]
    filtered_node_ids = {node["id"] for node in filtered_nodes if _is_mapping(node) and isinstance(node.get("id"), str)}
    filtered_edges = [
        edge
        for edge in workflow_edges
        if _is_mapping(edge)
        and edge.get("type") == "default"

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Open the saved workflow in the InvokeAI workflow editor and re-save it so nodes/edges are serialized in the current list-based schema.
  2. Inspect the stored workflow JSON (workflow library/DB) and fix or remove the malformed record.
  3. Update the workflow from the version it was authored in before using it in a call_saved_workflow batch node.
  4. Catch UnsupportedWorkflowNodeError around batch building and skip/report the offending workflow.

Example fix

// before
workflow = {"id": "w1", "nodes": {"n1": {...}}, "edges": []}  # nodes as dict
// after
workflow = {"id": "w1", "nodes": [{"id": "n1", ...}], "edges": []}  # lists
Defensive patterns

Strategy: type-guard

Validate before calling

def child_workflow_is_wellformed(workflow: dict) -> bool:
    return isinstance(workflow.get("nodes"), list) and isinstance(workflow.get("edges"), list)

if not child_workflow_is_wellformed(saved_workflow):
    raise ValueError("saved workflow must have list-typed nodes and edges")

Type guard

def is_list_workflow(w: object) -> bool:
    return isinstance(w, dict) and isinstance(w.get("nodes"), list) and isinstance(w.get("edges"), list)

Try / catch

try:
    results = build_batch_child_workflow_session_results(...)
except UnsupportedWorkflowNodeError:
    results = []  # skip batch; surface workflow as invalid in UI

Prevention

When it happens

Trigger: Executing a batch whose call_saved_workflow node references a saved workflow whose stored JSON has nodes/edges absent, null, dicts, or otherwise not arrays — e.g. a hand-edited or partially migrated workflow record in the workflow library.

Common situations: Workflows authored by older InvokeAI versions or third-party tools with a different schema; corrupted rows after a database import/export; users pasting workflow JSON that got mangled (nodes as an object keyed by id instead of a list).

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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