{"record":{"id":"eedc2fb7b0618328","repo":"invoke-ai/InvokeAI","slug":"the-selected-saved-workflow-must-not-contain-more","errorCode":null,"errorMessage":"The selected saved workflow must not contain more than one workflow_return node.","messagePattern":"The selected saved workflow must not contain more than one workflow_return node\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/session_processor/workflow_call_runtime.py","lineNumber":145,"sourceCode":"    @staticmethod\n    def get_waiting_workflow_call_invocation(queue_item: SessionQueueItem) -> CallSavedWorkflowInvocation:\n        waiting_frame = queue_item.session.waiting_workflow_call\n        if waiting_frame is None:\n            raise ValueError(\"Execution state is not waiting on a workflow call.\")\n        invocation = queue_item.session.execution_graph.nodes.get(waiting_frame.prepared_call_node_id)\n        if not isinstance(invocation, CallSavedWorkflowInvocation):\n            raise ValueError(\"Waiting workflow call frame does not point to a call_saved_workflow invocation.\")\n        return invocation\n\n    @staticmethod\n    def get_child_workflow_return_output(child_session: GraphExecutionState) -> WorkflowReturnOutput:\n        workflow_return_node_ids = [\n            node_id for node_id, node in child_session.graph.nodes.items() if node.get_type() == \"workflow_return\"\n        ]\n        if not workflow_return_node_ids:\n            raise ValueError(\"The selected saved workflow must contain exactly one workflow_return node.\")\n        if len(workflow_return_node_ids) > 1:\n            raise ValueError(\"The selected saved workflow must not contain more than one workflow_return node.\")\n\n        workflow_return_node_id = workflow_return_node_ids[0]\n        prepared_return_node_ids = child_session.source_prepared_mapping.get(workflow_return_node_id, set())\n        if len(prepared_return_node_ids) != 1:\n            raise ValueError(\n                \"The selected saved workflow produced an unsupported number of workflow_return executions.\"\n            )\n\n        prepared_return_node_id = next(iter(prepared_return_node_ids))\n        output = child_session.results.get(prepared_return_node_id)\n        if not isinstance(output, WorkflowReturnOutput):\n            raise ValueError(\"The selected saved workflow did not produce a valid workflow_return output.\")\n\n        return output\n\n    def resume_waiting_workflow_call(self, queue_item: SessionQueueItem) -> None:\n        invocation = self.get_waiting_workflow_call_invocation(queue_item)\n        child_session = queue_item.session.waiting_workflow_call_child_session","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/session_processor/workflow_call_runtime.py#L127-L163","documentation":"When a workflow-call node executes a saved child workflow, InvokeAI requires exactly one workflow_return node in that child graph so the parent knows which node's output to hand back. This ValueError is raised in get_child_workflow_return_output when the child graph contains more than one workflow_return node, making the return value ambiguous.","triggerScenarios":"Calling a child workflow via a workflow_call invocation whose saved graph was edited (or duplicated) to include two or more workflow_return nodes; the error surfaces when the parent resumes from the completed/waiting child session (resume_waiting_workflow_call or _resume_parent_from_completed_child).","commonSituations":"Duplicating a workflow that already had a workflow_return node, manually editing a saved workflow JSON, or merging two workflows without removing one of the return nodes.","solutions":["Open the saved child workflow in the editor and delete the extra workflow_return node(s), leaving exactly one","Inspect the workflow JSON (graph.nodes) and remove all but one node whose type is workflow_return","Re-save the workflow and re-run the parent workflow","If the workflow was duplicated programmatically, fix the duplication logic to strip duplicate return nodes"],"exampleFix":"// before: graph with two workflow_return nodes\n{\"nodes\": {\"a\": {\"type\": \"workflow_return\", ...}, \"b\": {\"type\": \"workflow_return\", ...}}}\n// after: keep exactly one\n{\"nodes\": {\"a\": {\"type\": \"workflow_return\", ...}}}","handlingStrategy":"validation","validationCode":"return_ids = [nid for nid, n in workflow.graph.nodes.items() if n.get_type() == 'workflow_return']\nif len(return_ids) != 1:\n    raise ValueError(f\"Saved workflow must contain exactly one workflow_return node (found {len(return_ids)}).\")","typeGuard":"def has_single_return(graph) -> bool:\n    return sum(1 for n in graph.nodes.values() if n.get_type() == \"workflow_return\") == 1","tryCatchPattern":"try:\n    output = runtime.get_child_workflow_return_output(child_session)\nexcept ValueError as e:\n    logger.error(f\"Child workflow misconfigured: {e}\")\n    # fix the workflow, then re-run","preventionTips":["After editing or duplicating a workflow, count workflow_return nodes before saving","Keep workflow_return addition confined to the workflow editor's dedicated action","Add a save-time lint that rejects graphs with != 1 workflow_return node","Review merged workflow JSON for duplicated return nodes"],"tags":["workflow","validation","graph"],"backgroundTag":"workflow-return-node-count-invalid","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}