invoke-ai/InvokeAI · error · NotExecutableNodeError

NotExecutableNodeError

Error message

NotExecutableNodeError

What it means

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.

Source

Thrown at invokeai/app/invocations/batch.py:52


class NotExecutableNodeError(Exception):
    def __init__(self, message: str = "This class should never be executed or instantiated directly."):
        super().__init__(message)

    pass


class BaseBatchInvocation(BaseInvocation):
    batch_group_id: BATCH_GROUP_IDS = InputField(
        default="None",
        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.",
        input=Input.Direct,
        title="Batch Group",
    )

    def __init__(self):
        raise NotExecutableNodeError()


@invocation(
    "image_batch",
    title="Image Batch",
    tags=["primitives", "image", "batch", "special"],
    category="batch",
    version="1.0.0",
    classification=Classification.Special,
)
class ImageBatchInvocation(BaseBatchInvocation):
    """Create a batched generation, where the workflow is executed once for each image in the batch."""

    images: list[ImageField] = InputField(
        min_length=1,
        description="The images to batch over",
    )

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Do not instantiate or queue this node; it is a schema-only placeholder used by the batch processor.
  2. Use the batch processor / graph expansion (collect nodes and batch settings) instead of executing it directly.
  3. If you need similar zipping behavior in code, iterate collections in Python before building the graph.

Example fix

// before
node = CollectBatchedInvocations()  # raises

// after
# build image_batch / range nodes and let the batch processor zip them via batch_group
batch = Batch.from_batch_data_collection(...)  # executor expands, never runs the placeholder
Defensive patterns

Strategy: type-guard

Validate before calling

NON_EXECUTABLE = ("collect_batched_invocations", "image_batch", "image_generator", "string_batch", "string_generator")
assert node.type not in NON_EXECUTABLE, f"{node.type} must not be queued for execution"

Type guard

def is_executable(node) -> bool:
    return not isinstance(node, (CollectBatchedInvocations, ImageBatch, ImageGenerator, StringBatch))

Try / catch

try:
    node = CollectBatchedInvocations()
except NotExecutableNodeError:
    node = None  # placeholder node; handle via batch processor instead

Prevention

When it happens

Trigger: Attempting to instantiate CollectBatchedInvocations(), or including it as a runnable node in a graph that gets queued for execution.

Common situations: 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.

Related errors


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