invoke-ai/InvokeAI · error · InvalidEdgeError
Iterator input type does not match iterator output type ({ed
Error message
Iterator input type does not match iterator output type ({edge}): {err} What it means
InvalidEdgeError raised by _validate_iterator_edge_rules() when an edge into an IterateInvocation's 'collection' input would break the invariant that the iterator's item output type matches its collection element type. _is_iterator_connection_valid() returns the reason, which is embedded in the message. This runs at add-edge time, before validate_self().
Source
Thrown at invokeai/app/services/shared/graph.py:1948
raise InvalidEdgeError(f"Edge creates a cycle in the graph ({edge})")
def _validate_edge_field_compatibility(
self, edge: Edge, source_node: BaseInvocation, destination_node: BaseInvocation
) -> None:
if isinstance(destination_node, CallSavedWorkflowInvocation) and is_call_saved_workflow_dynamic_input(
edge.destination.field
):
return
if not are_connections_compatible(source_node, edge.source.field, destination_node, edge.destination.field):
raise InvalidEdgeError(f"Field types are incompatible ({edge})")
def _validate_iterator_edge_rules(
self, edge: Edge, source_node: BaseInvocation, destination_node: BaseInvocation
) -> None:
if isinstance(destination_node, IterateInvocation) and edge.destination.field == COLLECTION_FIELD:
err = self._is_iterator_connection_valid(edge.destination.node_id, new_input=edge.source)
if err is not None:
raise InvalidEdgeError(f"Iterator input type does not match iterator output type ({edge}): {err}")
if isinstance(source_node, IterateInvocation) and edge.source.field == ITEM_FIELD:
err = self._is_iterator_connection_valid(edge.source.node_id, new_output=edge.destination)
if err is not None:
raise InvalidEdgeError(f"Iterator output type does not match iterator input type ({edge}): {err}")
def _validate_collector_edge_rules(
self,
edge: Edge,
source_node: BaseInvocation,
destination_node: BaseInvocation,
allow_inputless_source_collector: bool,
) -> None:
if isinstance(destination_node, CollectInvocation) and edge.destination.field in (ITEM_FIELD, COLLECTION_FIELD):
err = self._is_collector_connection_valid(
edge.destination.node_id, new_input=edge.source, new_input_field=edge.destination.field
)
if err is not None:View on GitHub (pinned to 0b6a024f2f)
Solutions
- Ensure the edge into 'collection' comes from an output whose type is a list of the expected item type
- Adjust the iterator's downstream consumers or upstream source so input and item types agree
- Wrap single items in a collect/batch node to produce the expected collection type
- Update the custom node pack if its output type changed
Example fix
// before g.add_edge(prompt, "prompt", iterate, "collection") # str into collection // after g.add_edge(batch_prompt, "collection", iterate, "collection") # list[str]
Defensive patterns
Strategy: validation
Validate before calling
def iterator_input_ok(graph, iterate_node_id, source) -> bool:
return graph._is_iterator_connection_valid(
iterate_node_id, new_input=source
) is None
if iterator_input_ok(g, "iterate_1", EdgeSource(node_id="batch_1", field="collection")):
g.add_edge("batch_1", "collection", "iterate_1", "collection") Type guard
def is_compatible_iterator_input(graph, iterate_node, source) -> bool:
if not isinstance(iterate_node, IterateInvocation):
return False
return graph._is_iterator_connection_valid(
iterate_node.id, new_input=source
) is None Try / catch
from invokeai.app.services.shared.graph import InvalidEdgeError
try:
g.add_edge(src, src_field, iterate, "collection")
except InvalidEdgeError as e:
if "Iterator input type does not match" in str(e):
wrap_source_in_batch_node(src) # emit a proper collection type
else:
raise Prevention
- Feed iterators only outputs typed as a collection of the intended item type
- When changing an iterator's upstream, re-check all item consumers downstream
- Validate iterate/collect graphs with validate_self() before saving
When it happens
Trigger: Calling g.add_edge(x, field, iterate_node, "collection") where x.field's type conflicts with the type the iterator emits as 'item' (checked via _is_iterator_connection_valid with new_input=edge.source).
Common situations: Feeding a non-collection or wrong-element-type output into an iterator, changing the iterator's upstream after downstream consumers were wired for the old item type, hand-edited workflow JSON.
Related errors
- Edge source and target types do not match ({edge})
- Invalid iterator node ({node.id}): {err}
- Field types are incompatible ({edge})
- Expected PreTrainedModel for text encoder, got {type(text_en
- Expected PreTrainedTokenizerBase for tokenizer, got {type(to
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/98d78d7b46e40ce0.
Report an issue: GitHub.