invoke-ai/InvokeAI · error · ValueError

The selected saved workflow must contain exactly one workflo

Error message

The selected saved workflow must contain exactly one workflow_return node.

What it means

When resuming a parent from a completed child workflow, the runtime extracts the child's output from its workflow_return node. If the child graph has none, ValueError is raised: a called saved workflow must terminate in exactly one workflow_return node to deliver a value back to the caller.

Source

Thrown at invokeai/app/services/session_processor/workflow_call_runtime.py:143

        self._session_runner = session_runner

    @staticmethod
    def get_waiting_workflow_call_invocation(queue_item: SessionQueueItem) -> CallSavedWorkflowInvocation:
        waiting_frame = queue_item.session.waiting_workflow_call
        if waiting_frame is None:
            raise ValueError("Execution state is not waiting on a workflow call.")
        invocation = queue_item.session.execution_graph.nodes.get(waiting_frame.prepared_call_node_id)
        if not isinstance(invocation, CallSavedWorkflowInvocation):
            raise ValueError("Waiting workflow call frame does not point to a call_saved_workflow invocation.")
        return invocation

    @staticmethod
    def get_child_workflow_return_output(child_session: GraphExecutionState) -> WorkflowReturnOutput:
        workflow_return_node_ids = [
            node_id for node_id, node in child_session.graph.nodes.items() if node.get_type() == "workflow_return"
        ]
        if not workflow_return_node_ids:
            raise ValueError("The selected saved workflow must contain exactly one workflow_return node.")
        if len(workflow_return_node_ids) > 1:
            raise ValueError("The selected saved workflow must not contain more than one workflow_return node.")

        workflow_return_node_id = workflow_return_node_ids[0]
        prepared_return_node_ids = child_session.source_prepared_mapping.get(workflow_return_node_id, set())
        if len(prepared_return_node_ids) != 1:
            raise ValueError(
                "The selected saved workflow produced an unsupported number of workflow_return executions."
            )

        prepared_return_node_id = next(iter(prepared_return_node_ids))
        output = child_session.results.get(prepared_return_node_id)
        if not isinstance(output, WorkflowReturnOutput):
            raise ValueError("The selected saved workflow did not produce a valid workflow_return output.")

        return output

    def resume_waiting_workflow_call(self, queue_item: SessionQueueItem) -> None:

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Open the saved workflow in the editor and add exactly one workflow_return node wired to the desired output, then re-save and retry the call.
  2. Validate the workflow before calling: assert exactly one node with get_type() == 'workflow_return' exists in the graph.
  3. Remove/hide duplicate workflow_return nodes if you hit the companion 'more than one' error, then re-run.
  4. Catch this ValueError and show a workflow-configuration error to the user pointing at the missing return node.

Example fix

// before: child graph ends at image node
nodes: [t2i]
// after
nodes: [t2i, workflow_return]
edges: t2i.image -> workflow_return.image
Defensive patterns

Strategy: validation

Validate before calling

returns = [n for n in wf["nodes"] if n.get("data", {}).get("type") == "workflow_return"]
if len(returns) != 1:
    raise WorkflowConfigError("saved workflow must contain exactly one workflow_return node")

Type guard

def has_single_workflow_return(graph) -> bool:
    ids = [nid for nid, n in graph.nodes.items() if n.get_type() == "workflow_return"]
    return len(ids) == 1

Try / catch

try:
    output = get_child_workflow_return_output(child_session)
except ValueError as e:
    if "workflow_return" in str(e):
        raise WorkflowConfigError("fix saved workflow return node") from e

Prevention

When it happens

Trigger: get_child_workflow_return_output scans child_session.graph.nodes for get_type() == 'workflow_return' and finds zero matches — i.e. the saved workflow was called but lacks a workflow_return terminal node.

Common situations: Saving a workflow in the editor without adding a workflow_return node before using it in call_saved_workflow; older workflows predating the workflow_return requirement; workflows truncated during export/import; validation bypassed by calling the API directly.

Related errors


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