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
- Open the saved workflow in the InvokeAI workflow editor and re-save it so nodes/edges are serialized in the current list-based schema.
- Inspect the stored workflow JSON (workflow library/DB) and fix or remove the malformed record.
- Update the workflow from the version it was authored in before using it in a call_saved_workflow batch node.
- 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
- Re-save old/external workflows in the current workflow editor before use in batch calls
- Validate workflow JSON schema on import/export
- Do not hand-edit stored workflow records in the DB
- Verify nodes/edges are arrays when migrating workflows between versions
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- call_saved_workflow does not yet support child workflows tha
- Unsupported batch group id '{batch_group_id}' in called work
- call_saved_workflow batch child workflow node inputs are mal
- call_saved_workflow batch child workflow node is missing req
- call_saved_workflow batch child workflow node '{node_data.ge
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/6d3b67fd8c61cddc.
Report an issue: GitHub.