{"record":{"id":"686b6f3525108610","repo":"invoke-ai/InvokeAI","slug":"notexecutablenodeerror","errorCode":null,"errorMessage":"NotExecutableNodeError","messagePattern":"NotExecutableNodeError","errorType":"exception","errorClass":"NotExecutableNodeError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/batch.py","lineNumber":52,"sourceCode":"\n\nclass NotExecutableNodeError(Exception):\n    def __init__(self, message: str = \"This class should never be executed or instantiated directly.\"):\n        super().__init__(message)\n\n    pass\n\n\nclass BaseBatchInvocation(BaseInvocation):\n    batch_group_id: BATCH_GROUP_IDS = InputField(\n        default=\"None\",\n        description=\"The ID of this batch node's group. If provided, all batch nodes in with the same ID will be 'zipped' before execution, and all nodes' collections must be of the same size.\",\n        input=Input.Direct,\n        title=\"Batch Group\",\n    )\n\n    def __init__(self):\n        raise NotExecutableNodeError()\n\n\n@invocation(\n    \"image_batch\",\n    title=\"Image Batch\",\n    tags=[\"primitives\", \"image\", \"batch\", \"special\"],\n    category=\"batch\",\n    version=\"1.0.0\",\n    classification=Classification.Special,\n)\nclass ImageBatchInvocation(BaseBatchInvocation):\n    \"\"\"Create a batched generation, where the workflow is executed once for each image in the batch.\"\"\"\n\n    images: list[ImageField] = InputField(\n        min_length=1,\n        description=\"The images to batch over\",\n    )\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/batch.py#L34-L70","documentation":"CollectBatchedInvocations (the batch group primitive) is a non-executable schema node: its __init__ unconditionally raises NotExecutableNodeError. It exists only to participate in graph expansion (zipping batch groups), never to be queued and run by the executor.","triggerScenarios":"Attempting to instantiate CollectBatchedInvocations(), or including it as a runnable node in a graph that gets queued for execution.","commonSituations":"Building graphs programmatically and treating the batch group node like a normal invocation; the workflow editor accidentally leaving a batch primitive in the execution path.","solutions":["Do not instantiate or queue this node; it is a schema-only placeholder used by the batch processor.","Use the batch processor / graph expansion (collect nodes and batch settings) instead of executing it directly.","If you need similar zipping behavior in code, iterate collections in Python before building the graph."],"exampleFix":"// before\nnode = CollectBatchedInvocations()  # raises\n\n// after\n# build image_batch / range nodes and let the batch processor zip them via batch_group\nbatch = Batch.from_batch_data_collection(...)  # executor expands, never runs the placeholder","handlingStrategy":"type-guard","validationCode":"NON_EXECUTABLE = (\"collect_batched_invocations\", \"image_batch\", \"image_generator\", \"string_batch\", \"string_generator\")\nassert node.type not in NON_EXECUTABLE, f\"{node.type} must not be queued for execution\"","typeGuard":"def is_executable(node) -> bool:\n    return not isinstance(node, (CollectBatchedInvocations, ImageBatch, ImageGenerator, StringBatch))","tryCatchPattern":"try:\n    node = CollectBatchedInvocations()\nexcept NotExecutableNodeError:\n    node = None  # placeholder node; handle via batch processor instead","preventionTips":["Treat *Batch / *Generator primitives as schema-only expansion nodes","Always execute graphs via the batch processor, not the raw executor","Never instantiate placeholder invocations directly"],"tags":["non-executable-node","batch","misuse"],"backgroundTag":"non-executable-node","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}