invoke-ai/InvokeAI · error · InvalidEdgeError

Field types are incompatible ({edge})

Error message

Field types are incompatible ({edge})

What it means

InvalidEdgeError raised by _validate_edge_field_compatibility() when are_connections_compatible() finds the edge's source output type incompatible with the destination input type. Dynamic inputs on CallSavedWorkflowInvocation nodes are exempt from this check.

Source

Thrown at invokeai/app/services/shared/graph.py:1940

            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(
        self, edge: Edge, source_node: BaseInvocation, destination_node: BaseInvocation
    ) -> None:
        if isinstance(destination_node, IterateInvocation) and edge.destination.field == COLLECTION_FIELD:
            err = self._is_iterator_connection_valid(edge.destination.node_id, new_input=edge.source)
            if err is not None:
                raise InvalidEdgeError(f"Iterator input type does not match iterator output type ({edge}): {err}")

        if isinstance(source_node, IterateInvocation) and edge.source.field == ITEM_FIELD:
            err = self._is_iterator_connection_valid(edge.source.node_id, new_output=edge.destination)
            if err is not None:
                raise InvalidEdgeError(f"Iterator output type does not match iterator input type ({edge}): {err}")

    def _validate_collector_edge_rules(
        self,
        edge: Edge,
        source_node: BaseInvocation,

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Connect fields whose types actually match (check node field annotations)
  2. Insert a conversion node (e.g. VAE encode/decode) between mismatched types
  3. Update or pin the custom node pack that changed its field types
  4. Use the UI's connection validation, which only offers compatible fields

Example fix

// before
g.add_edge(load_image, "image", inpaint_mask, "latents")  # mismatch
// after
latents = vae_encode(load_image, "image")
g.add_edge(vae_encode, "latents", inpaint_mask, "latents")
Defensive patterns

Strategy: validation

Validate before calling

from invokeai.app.services.shared.graph import are_connections_compatible

def can_connect(graph, src_id, src_field, dst_id, dst_field) -> bool:
    return are_connections_compatible(
        graph.get_node(src_id), src_field,
        graph.get_node(dst_id), dst_field,
    )

assert can_connect(g, "img_1", "image", "denoise_1", "image")

Type guard

def fields_compatible(graph, edge) -> bool:
    try:
        return are_connections_compatible(
            graph.get_node(edge.source.node_id), edge.source.field,
            graph.get_node(edge.destination.node_id), edge.destination.field,
        )
    except NodeNotFoundError:
        return False

Try / catch

from invokeai.app.services.shared.graph import InvalidEdgeError

try:
    g.add_edge(src, src_field, dst, dst_field)
except InvalidEdgeError as e:
    if "incompatible" in str(e):
        insert_conversion_node(src, dst)  # e.g. VAE encode/decode
    else:
        raise

Prevention

When it happens

Trigger: Calling g.add_edge() (or add_edge performed during deserialization) where the source field's output type doesn't match the destination field's input type, e.g. image output into a latents input.

Common situations: Connecting fields with similar names but different types, custom nodes whose types changed after an update, scripts wiring fields by name without checking types.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/d7b2d75edd5b5e78. Report an issue: GitHub.