{"record":{"id":"e6e0ede5c97e7f4a","repo":"invoke-ai/InvokeAI","slug":"call-saved-workflow-image-generator-backed-batch-c","errorCode":null,"errorMessage":"call_saved_workflow image-generator-backed batch child workflows require runtime services","messagePattern":"call_saved_workflow image-generator-backed batch child workflows require runtime services","errorType":"exception","errorClass":"UnsupportedWorkflowNodeError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/session_processor/workflow_call_batch.py","lineNumber":589,"sourceCode":"        node_type = node_data.get(\"type\")\n        if not isinstance(node_id, str) or not isinstance(node_type, str):\n            continue\n        if node_type.endswith(\"_generator\"):\n            continue\n        if node_type not in SUPPORTED_BATCH_TYPES:\n            continue\n\n        field_name = BATCH_FIELD_NAMES[node_type]\n        generator_source_id = _resolve_batch_items_from_inputs(node_id, field_name, workflow_edges, workflow_nodes)\n        if generator_source_id is not None:\n            generator_node = workflow_nodes.get(generator_source_id)\n            if generator_node is None:\n                raise UnsupportedWorkflowNodeError(\n                    f\"call_saved_workflow generator-backed batch child workflow is missing generator node '{generator_source_id}'\"\n                )\n            generator_node_type = generator_node[\"data\"].get(\"type\") if _is_invocation_node(generator_node) else None\n            if generator_node_type == \"image_generator\" and services is None and resolve_generator_items:\n                raise UnsupportedWorkflowNodeError(\n                    \"call_saved_workflow image-generator-backed batch child workflows require runtime services\"\n                )\n            batch_items = (\n                _resolve_generator_items(generator_node, services, user_id, maximum_children)\n                if resolve_generator_items\n                else _get_generator_placeholder_items(generator_node)\n            )\n            used_generator_node_ids.add(generator_source_id)\n            if not batch_items:\n                raise UnsupportedWorkflowNodeError(\n                    f\"call_saved_workflow generator-backed batch child workflow node '{generator_source_id}' produced no batch items\"\n                )\n        else:\n            batch_items = _get_batch_items(node_data, field_name)\n            if not batch_items:\n                raise UnsupportedWorkflowNodeError(\n                    f\"call_saved_workflow batch child workflow node '{node_id}' must provide at least one batch item\"\n                )","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/session_processor/workflow_call_batch.py#L571-L607","documentation":"When a batch-collect node inside a called saved workflow pulls its items from an 'image_generator' node, InvokeAI must query the image database via runtime services to enumerate the images. If build_batch_child_workflow_session_results is invoked without a services object (services=None) while generator-item resolution is enabled, the library cannot expand the batch and raises UnsupportedWorkflowNodeError.","triggerScenarios":"Calling build_batch_child_workflow_session_results (or build_child_workflow_session_results) with a saved workflow whose batch node (e.g. batch/iterate) is wired to an image_generator node, without passing services, while resolve_generator_items=True (the default).","commonSituations":"Unit tests or tooling that build child sessions in isolation without dependency injection; offline/preprocessing scripts that call the batch builder directly; calling build_batch_child_workflow_sessions instead of the placeholder-based variant.","solutions":["Pass the application services object (services=...) to build_batch_child_workflow_session_results / build_child_workflow_session_results so image_generator items can be resolved from the database.","If no services are available and you only need placeholder sessions, call with resolve_generator_items=False so _get_generator_placeholder_items is used instead of hitting the DB.","Replace the image_generator wiring in the saved workflow with an inline collection batch node carrying explicit items.","Pre-check the workflow: resolve the batch node's generator source and skip/branch before calling when its type is image_generator and services are unavailable."],"exampleFix":"// before\nresults = build_child_workflow_session_results(\n    parent_session=session, workflow=wf, workflow_inputs=inputs,\n    call_frame=frame, maximum_children=10)\n// after\nresults = build_child_workflow_session_results(\n    parent_session=session, workflow=wf, workflow_inputs=inputs,\n    call_frame=frame, maximum_children=10,\n    services=services, user_id=user_id)","handlingStrategy":"validation","validationCode":"def generator_needs_services(workflow):\n    for node in workflow.get(\"nodes\", []):\n        if node.get(\"data\", {}).get(\"type\") == \"image_generator\":\n            return True\n    return False\nif generator_needs_services(wf) and services is None:\n    raise ValueError(\"image_generator batch requires services\")","typeGuard":"def has_services(services) -> bool:\n    return services is not None","tryCatchPattern":"try:\n    results = build_child_workflow_session_results(..., services=services)\nexcept UnsupportedWorkflowNodeError as e:\n    if \"require runtime services\" in str(e):\n        results = build_child_workflow_session_results(..., resolve_generator_items=False)","preventionTips":["Always pass the app services object when building child sessions in production code paths","Use resolve_generator_items=False for offline/placeholder builds","Lint test fixtures that construct batch workflows with image_generator nodes","Document that image_generator batches are a runtime-only capability"],"tags":["invokeai","batch","workflow-call","missing-dependency"],"backgroundTag":"workflow-batch-generator-requires-services","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}