invoke-ai/InvokeAI · error · InvalidEdgeError

Field types are incompatible

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.

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.

Appendix: 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)