{"record":{"id":"1c505f6b6cc8b676","repo":"invoke-ai/InvokeAI","slug":"edge-source-and-target-types-do-not-match-edge","errorCode":null,"errorMessage":"Edge source and target types do not match ({edge})","messagePattern":"Edge source and target types do not match \\((.+?)\\)","errorType":"validation","errorClass":"InvalidEdgeError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/shared/graph.py","lineNumber":1848,"sourceCode":"    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,\n                destination_node,\n                edge.destination.field,\n            ):\n                raise InvalidEdgeError(f\"Edge source and target types do not match ({edge})\")\n\n    def _validate_special_nodes(self) -> None:\n        # TODO: may need to validate all iterators & collectors in subgraphs so edge connections in parent graphs will be available\n        for node in self.nodes.values():\n            if isinstance(node, IterateInvocation):\n                err = self._is_iterator_connection_valid(node.id)\n                if err is not None:\n                    raise InvalidEdgeError(f\"Invalid iterator node ({node.id}): {err}\")\n            if isinstance(node, CollectInvocation):\n                err = self._is_collector_connection_valid(node.id)\n                if err is not None:\n                    raise InvalidEdgeError(f\"Invalid collector node ({node.id}): {err}\")\n\n    def validate_self(self) -> None:\n        \"\"\"\n        Validates the graph.\n\n        Raises an exception if the graph is invalid:","sourceCodeStart":1830,"sourceCodeEnd":1866,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/shared/graph.py#L1830-L1866","documentation":"InvalidEdgeError raised when validating a graph whose existing edge connects fields whose output/input types fail are_connections_compatible(). It guards the whole stored edge set in validate_self(), distinct from the per-edge add-path check (_validate_edge_field_compatibility). Ensures no edge carries data of the wrong type between nodes.","triggerScenarios":"validate_self() iterating self.edges where any edge's source field output type mismatches the destination field's input type, typically after node field definitions changed or the graph was hand-constructed/edited.","commonSituations":"Custom node packs updated and changed a field type (e.g. image -> latents), workflows edited by hand in JSON, connecting a string field to an image field via a script.","solutions":["Identify the failing edge from the message (it includes the edge object)","Check get_output_field_type of the source field vs get_input_field_type of the destination field","Insert a type-conversion node between the two nodes or connect to a matching-typed field","Re-open and fix the workflow in the UI, which enforces type compatibility on connect","Pin or update the custom node pack that changed the field type"],"exampleFix":"// before\ng.add_edge(load_image, \"image\", save_latents, \"latents\")  # type mismatch\n// after\ng.add_edge(load_image, \"image\", resize_image, \"image\")\ng.add_edge(vae_encode, \"latents\", save_latents, \"latents\")","handlingStrategy":"validation","validationCode":"from invokeai.app.services.shared.graph import are_connections_compatible\n\ndef edge_types_ok(graph, edge):\n    return are_connections_compatible(\n        graph.get_node(edge.source.node_id), edge.source.field,\n        graph.get_node(edge.destination.node_id), edge.destination.field,\n    )\n\nassert all(edge_types_ok(g, e) for e in g.edges)","typeGuard":"def edge_is_typed(graph, edge) -> bool:\n    try:\n        return are_connections_compatible(\n            graph.get_node(edge.source.node_id), edge.source.field,\n            graph.get_node(edge.destination.node_id), edge.destination.field,\n        )\n    except NodeNotFoundError:\n        return False","tryCatchPattern":"from invokeai.app.services.shared.graph import InvalidEdgeError\n\ntry:\n    graph.validate_self()\nexcept InvalidEdgeError as e:\n    logger.error(\"bad edge: %s\", e)\n    # remove/redirect the offending edge named in the message","preventionTips":["Re-validate every stored workflow after installing or updating custom node packs","Prefer building graphs in the UI or via add_edge(), which validates types on connect","Never hand-edit workflow JSON field names without checking types"],"tags":["invokeai","graph-validation","type-mismatch","edges"],"backgroundTag":"edge-type-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}