invoke-ai/InvokeAI · error · InvalidEdgeError
Field types are incompatible ({edge})
Error message
Field types are incompatible ({edge}) What it means
InvalidEdgeError raised by _validate_edge_field_compatibility() when are_connections_compatible() finds the edge's source output type incompatible with the destination input type. Dynamic inputs on CallSavedWorkflowInvocation nodes are exempt from this check.
Source
Thrown at invokeai/app/services/shared/graph.py:1940
not isinstance(destination_node, CollectInvocation) or edge.destination.field != ITEM_FIELD
):
raise InvalidEdgeError(f"Edge already exists ({edge})")
def _validate_edge_would_not_create_cycle(self, edge: Edge) -> None:
graph = self.nx_graph_flat()
graph.add_edge(edge.source.node_id, edge.destination.node_id)
if not nx.is_directed_acyclic_graph(graph):
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,View on GitHub (pinned to 0b6a024f2f)
Solutions
- Connect fields whose types actually match (check node field annotations)
- Insert a conversion node (e.g. VAE encode/decode) between mismatched types
- Update or pin the custom node pack that changed its field types
- Use the UI's connection validation, which only offers compatible fields
Example fix
// before g.add_edge(load_image, "image", inpaint_mask, "latents") # mismatch // after latents = vae_encode(load_image, "image") g.add_edge(vae_encode, "latents", inpaint_mask, "latents")
Defensive patterns
Strategy: validation
Validate before calling
from invokeai.app.services.shared.graph import are_connections_compatible
def can_connect(graph, src_id, src_field, dst_id, dst_field) -> bool:
return are_connections_compatible(
graph.get_node(src_id), src_field,
graph.get_node(dst_id), dst_field,
)
assert can_connect(g, "img_1", "image", "denoise_1", "image") Type guard
def fields_compatible(graph, edge) -> bool:
try:
return are_connections_compatible(
graph.get_node(edge.source.node_id), edge.source.field,
graph.get_node(edge.destination.node_id), edge.destination.field,
)
except NodeNotFoundError:
return False Try / catch
from invokeai.app.services.shared.graph import InvalidEdgeError
try:
g.add_edge(src, src_field, dst, dst_field)
except InvalidEdgeError as e:
if "incompatible" in str(e):
insert_conversion_node(src, dst) # e.g. VAE encode/decode
else:
raise Prevention
- Check field types via get_output_field_type/get_input_field_type before wiring by name
- Use the UI, which only offers type-compatible fields for connection
- Re-validate workflows after upgrading custom node packs
When it happens
Trigger: Calling g.add_edge() (or add_edge performed during deserialization) where the source field's output type doesn't match the destination field's input type, e.g. image output into a latents input.
Common situations: Connecting fields with similar names but different types, custom nodes whose types changed after an update, scripts wiring fields by name without checking types.
Related errors
- Edge source and target types do not match ({edge})
- One or both nodes don't exist ({edge})
- Edge already exists ({edge})
- Edge creates a cycle in the graph ({edge})
- Iterator input type does not match iterator output type ({ed
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/d7b2d75edd5b5e78.
Report an issue: GitHub.