{"record":{"id":"b2a76144ed51550b","repo":"invoke-ai/InvokeAI","slug":"edge-source-node-edge-source-node-id-does-not-ex","errorCode":null,"errorMessage":"Edge source node {edge.source.node_id} does not exist in the graph","messagePattern":"Edge source node (.+?) does not exist in the graph","errorType":"validation","errorClass":"NodeNotFoundError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/shared/graph.py","lineNumber":1810,"sourceCode":"            pass\n\n    def _validate_unique_node_ids(self) -> None:\n        node_ids = [n.id for n in self.nodes.values()]\n        seen = set()\n        duplicate_node_ids = {nid for nid in node_ids if (nid in seen) or seen.add(nid)}\n        if duplicate_node_ids:\n            raise DuplicateNodeIdError(f\"Node ids must be unique, found duplicates {duplicate_node_ids}\")\n\n    def _validate_node_id_mapping(self) -> None:\n        for node_dict_id, node in self.nodes.items():\n            if node_dict_id != node.id:\n                raise NodeIdMismatchError(f\"Node ids must match, got {node_dict_id} and {node.id}\")\n\n    def _validate_edge_nodes_and_fields(self) -> None:\n        for edge in self.edges:\n            source_node = self.nodes.get(edge.source.node_id, None)\n            if source_node is None:\n                raise NodeNotFoundError(f\"Edge source node {edge.source.node_id} does not exist in the graph\")\n\n            destination_node = self.nodes.get(edge.destination.node_id, None)\n            if destination_node is None:\n                raise NodeNotFoundError(f\"Edge destination node {edge.destination.node_id} does not exist in the graph\")\n\n            if edge.source.field not in source_node.get_output_annotation().model_fields:\n                raise NodeFieldNotFoundError(\n                    f\"Edge source field {edge.source.field} does not exist in node {edge.source.node_id}\"\n                )\n\n            if edge.destination.field not in type(destination_node).model_fields:\n                if isinstance(destination_node, CallSavedWorkflowInvocation) and is_call_saved_workflow_dynamic_input(\n                    edge.destination.field\n                ):\n                    continue\n                raise NodeFieldNotFoundError(\n                    f\"Edge destination field {edge.destination.field} does not exist in node {edge.destination.node_id}\"\n                )","sourceCodeStart":1792,"sourceCodeEnd":1828,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/shared/graph.py#L1792-L1828","documentation":"NodeNotFoundError is raised when validating a graph and an edge's `source.node_id` does not exist as a key in the graph's nodes dict. Edges must connect two nodes present in the graph; a dangling source reference means the graph is invalid and cannot be executed.","triggerScenarios":"Adding an edge (add_edge / EdgeConnection) whose source.node_id references a node never added to the graph, or that was removed (delete_node) while its edges remained, or whose id was renamed after the edge was created.","commonSituations":"Deleting a node from a workflow without deleting its connected edges; hand-editing workflow JSON and changing a node id referenced by an edge; copying edges between graphs; API clients sending edge payloads with typos in node_id.","solutions":["Add the missing source node to the graph before/along with the edge","Delete the dangling edge referencing the removed node","Update the edge's source.node_id to the correct existing node id","Run graph validation and inspect the reported node_id to locate the broken reference"],"exampleFix":"# before\ngraph.delete_node(\"denoise\")  # edges still reference \"denoise\"\n\n# after\nfor edge in list(graph.edges):\n    if \"denoise\" in (edge.source.node_id, edge.destination.node_id):\n        graph.delete_edge(edge)\ngraph.delete_node(\"denoise\")","handlingStrategy":"validation","validationCode":"def check_edges_have_nodes(graph):\n    for edge in graph.edges:\n        if edge.source.node_id not in graph.nodes:\n            raise ValueError(f\"edge source {edge.source.node_id} missing\")\n    return True\n\ncheck_edges_have_nodes(graph)  # before adding/submitting","typeGuard":"def edge_source_exists(graph, edge) -> bool:\n    return edge.source.node_id in graph.nodes","tryCatchPattern":"from invokeai.app.services.shared.graph import NodeNotFoundError\ntry:\n    graph.add_edge(edge)\n    validate_graph(graph)\nexcept NodeNotFoundError as e:\n    logger.error(\"dangling edge endpoint: %s\", e)\n    graph.delete_edge(edge)","preventionTips":["Delete all edges attached to a node before deleting the node","Add both endpoint nodes before adding any edges","After renaming a node id, update every edge referencing the old id"],"tags":["graph","validation","invokeai","edges"],"backgroundTag":"graph-edge-dangling-node-reference","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}