invoke-ai/InvokeAI · error · NodeAlreadyExecutedError
Destination node {edge.destination.node_id} has already been
Error message
Destination node {edge.destination.node_id} has already been prepared or executed and cannot be linked to What it means
GraphExecution.add_edge throws NodeAlreadyExecutedError when the edge's destination node has already been prepared or executed. Adding an edge to a finished node would retroactively change execution inputs, so it is forbidden. Mutate the graph before it is queued or enqueue a modified copy.
Source
Thrown at invokeai/app/services/shared/graph.py:2867
self.graph.add_node(node)
def update_node(self, node_id: str, new_node: BaseInvocation) -> None:
if not self._is_node_updatable(node_id):
raise NodeAlreadyExecutedError(
f"Node {node_id} has already been prepared or executed and cannot be updated"
)
self.graph.update_node(node_id, new_node)
def delete_node(self, node_id: str) -> None:
if not self._is_node_updatable(node_id):
raise NodeAlreadyExecutedError(
f"Node {node_id} has already been prepared or executed and cannot be deleted"
)
self.graph.delete_node(node_id)
def add_edge(self, edge: Edge) -> None:
if not self._is_node_updatable(edge.destination.node_id):
raise NodeAlreadyExecutedError(
f"Destination node {edge.destination.node_id} has already been prepared or executed and cannot be linked to"
)
self.graph.add_edge(edge)
def delete_edge(self, edge: Edge) -> None:
if not self._is_node_updatable(edge.destination.node_id):
raise NodeAlreadyExecutedError(
f"Destination node {edge.destination.node_id} has already been prepared or executed and cannot have a source edge deleted"
)
self.graph.delete_edge(edge)
View on GitHub (pinned to 0b6a024f2f)
Solutions
- Add all edges before enqueueing the graph
- Create a new graph/queue item with the desired edge instead of editing the executed session
- Catch NodeAlreadyExecutedError and handle (skip edge, notify user)
- Guard with _is_node_updatable(edge.destination.node_id) before add_edge
Example fix
// before
execution.add_edge(edge) # raises if destination already executed
// after
if execution._is_node_updatable(edge.destination.node_id):
execution.add_edge(edge)
else:
g = execution._graph.model_copy(deep=True)
g.add_edge(edge)
# enqueue g as a new queue item Defensive patterns
Strategy: validation
Validate before calling
if not execution._is_node_updatable(edge.destination.node_id):
raise SkipMutation("destination already executed")
execution.add_edge(edge) Type guard
def edge_target_mutable(execution, edge: Edge) -> bool:
return execution._is_node_updatable(edge.destination.node_id) Try / catch
try:
execution.add_edge(edge)
except NodeAlreadyExecutedError:
enqueue_new_graph_with_edge(graph, edge) Prevention
- Add all edges before queueing
- Never feed executed nodes' outputs back into them via late edges
- Clone the graph for post-run modifications
When it happens
Trigger: Calling GraphExecution.add_edge(edge) where edge.destination.node_id is in the prepared/executed node list (_is_node_updatable returns False).
Common situations: Wiring late outputs into already-run nodes during a live session, editing graphs over the websocket while execution is in progress, or loop-style graphs that try to feed results back into executed nodes.
Related errors
- Destination node {edge.destination.node_id} has already been
- Edge source node {edge.source.node_id} does not exist in the
- Edge destination node {edge.destination.node_id} does not ex
- Edge source field {edge.source.field} does not exist in node
- Edge destination field {edge.destination.field} does not exi
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/203361ae99257547.
Report an issue: GitHub.