invoke-ai/InvokeAI · error · InvalidEdgeError
Edge already exists ({edge})
Error message
Edge already exists ({edge}) What it means
InvalidEdgeError raised by _validate_edge_destination_uniqueness() when a destination input field already has an incoming edge. Most input fields accept exactly one edge; only CollectInvocation's 'item' field may receive many. This prevents silently overwriting or duplicating a node's input.
Source
Thrown at invokeai/app/services/shared/graph.py:1924
"""Checks if the destination field for an edge is of type typing.Any"""
return get_input_field_type(self.get_node(edge.destination.node_id), edge.destination.field) == Any
def _is_destination_field_list_of_Any(self, edge: Edge) -> bool:
"""Checks if the destination field for an edge is of type typing.Any"""
return get_input_field_type(self.get_node(edge.destination.node_id), edge.destination.field) == list[Any]
def _get_edge_nodes(self, edge: Edge) -> tuple[BaseInvocation, BaseInvocation]:
try:
return self.get_node(edge.source.node_id), self.get_node(edge.destination.node_id)
except NodeNotFoundError:
raise InvalidEdgeError(f"One or both nodes don't exist ({edge})")
def _validate_edge_destination_uniqueness(self, edge: Edge, destination_node: BaseInvocation) -> None:
input_edges = self._get_input_edges(edge.destination.node_id, edge.destination.field)
if len(input_edges) > 0 and (
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(View on GitHub (pinned to 0b6a024f2f)
Solutions
- Remove the existing edge into that field before adding the new one
- If you need to merge multiple outputs, route them through a CollectInvocation item field
- Make graph construction idempotent (check for the edge before adding)
- In the UI, delete the old connection first when rewiring
Example fix
// before g.add_edge(a, "image", denoise, "image") g.add_edge(b, "image", denoise, "image") # duplicate destination // after g.add_edge(a, "image", denoise, "image") g.delete_edge(a, "image", denoise, "image") g.add_edge(b, "image", denoise, "image")
Defensive patterns
Strategy: validation
Validate before calling
def has_input_edge(graph, node_id: str, field: str) -> bool:
return any(
e.destination.node_id == node_id and e.destination.field == field
for e in graph.edges
)
if not has_input_edge(g, dst_id, field):
g.add_edge(src_id, src_field, dst_id, field) Type guard
def destination_is_free(graph, edge) -> bool:
return not any(
e.destination.node_id == edge.destination.node_id
and e.destination.field == edge.destination.field
for e in graph.edges
) Try / catch
from invokeai.app.services.shared.graph import InvalidEdgeError
try:
g.add_edge(src, "image", dst, "image")
except InvalidEdgeError as e:
if "already exists" in str(e):
g.delete_edge(src, "image", dst, "image")
g.add_edge(src, "image", dst, "image") # replace Prevention
- Make graph-building scripts idempotent: check for existing edges before adding
- Delete the old connection before rewiring an input field
- Use a CollectInvocation when multiple sources must feed one consumer
When it happens
Trigger: Calling g.add_edge() connecting a second edge into the same (node_id, field) destination that is not a CollectInvocation item field.
Common situations: Re-running graph-building scripts that add edges twice, wiring two outputs into a single non-collect input, UI/script mix-ups after editing an existing workflow.
Related errors
- Edge source and target types do not match ({edge})
- One or both nodes don't exist ({edge})
- Edge creates a cycle in the graph ({edge})
- Field types are incompatible ({edge})
- The selected saved workflow must contain exactly one workflo
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/132ae43f16fe9d4b.
Report an issue: GitHub.