{"record":{"id":"8313f9a7ea1489b1","repo":"invoke-ai/InvokeAI","slug":"edge-destination-field-edge-destination-field-do","errorCode":null,"errorMessage":"Edge destination field {edge.destination.field} does not exist in node {edge.destination.node_id}","messagePattern":"Edge destination field (.+?) does not exist in node (.+?)","errorType":"validation","errorClass":"NodeFieldNotFoundError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/shared/graph.py","lineNumber":1826,"sourceCode":"            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                )\n\n    def _validate_graph_is_acyclic(self) -> None:\n        graph = self.nx_graph_flat()\n        if not nx.is_directed_acyclic_graph(graph):\n            raise CyclicalGraphError(\"Graph contains cycles\")\n\n    def _validate_edge_type_compatibility(self) -> None:\n        for edge in self.edges:\n            destination_node = self.get_node(edge.destination.node_id)\n            if isinstance(destination_node, CallSavedWorkflowInvocation) and is_call_saved_workflow_dynamic_input(\n                edge.destination.field\n            ):\n                continue\n            if not are_connections_compatible(\n                self.get_node(edge.source.node_id),\n                edge.source.field,","sourceCodeStart":1808,"sourceCodeEnd":1844,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/shared/graph.py#L1808-L1844","documentation":"NodeFieldNotFoundError is raised when an edge's `destination.field` is not an input field (Pydantic model_fields) of the destination node's type. Dynamic inputs on CallSavedWorkflowInvocation nodes are exempted. The library throws this because writing into a nonexistent input would be silently ignored at execution time.","triggerScenarios":"Creating an edge whose destination.field does not match any input field of the destination node type — typos, referencing an input that was renamed/removed in a newer InvokeAI version, or feeding a dynamic-INPUT field on a non-CallSavedWorkflowInvocation node.","commonSituations":"Saved workflows from older InvokeAI versions whose node inputs changed after an upgrade; hand-edited workflow JSON; programmatic graph construction using guessed field names.","solutions":["Change the edge's destination.field to a real input field of the destination node (check type(destination_node).model_fields)","Point the edge at a node type that has the desired input field","Recreate the workflow in the current UI after upgrading InvokeAI","During workflow migration, remap obsolete input names before validating the graph"],"exampleFix":"# before\nEdgeConnection(node_id=\"denoise\", field=\"prompt_text\")\n\n# after\nEdgeConnection(node_id=\"denoise\", field=\"prompt\")  # actual input field","handlingStrategy":"validation","validationCode":"def check_edge_destination_fields(graph):\n    for edge in graph.edges:\n        dst = graph.nodes.get(edge.destination.node_id)\n        if dst and edge.destination.field not in type(dst).model_fields:\n            raise ValueError(f\"{edge.destination.node_id} has no input field {edge.destination.field}\")\n    return True\n\ncheck_edge_destination_fields(graph)","typeGuard":"def is_valid_destination_field(dst, field: str) -> bool:\n    return field in type(dst).model_fields or (\n        isinstance(dst, CallSavedWorkflowInvocation)\n        and is_call_saved_workflow_dynamic_input(field)\n    )","tryCatchPattern":"from invokeai.app.services.shared.graph import NodeFieldNotFoundError\ntry:\n    validate_graph(graph)\nexcept NodeFieldNotFoundError as e:\n    logger.error(\"edge writes to nonexistent input: %s\", e)","preventionTips":["Validate destination field names against type(node).model_fields before wiring edges","After InvokeAI upgrades, migrate saved workflows and remap renamed inputs","For dynamic-INPUT workflows, only rely on dynamic fields on CallSavedWorkflowInvocation nodes"],"tags":["graph","validation","invokeai","edges","fields"],"backgroundTag":"graph-edge-field-not-found","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}