Comfy-Org/ComfyUI · error · NodeNotFoundError

Node {node_id} not found

Error message

Node {node_id} not found

What it means

Raised as NodeNotFoundError by DynamicPrompt.get_node() in comfy_execution/graph.py when a node id is looked up in neither the ephemeral prompt (nodes created during execution) nor the original user prompt. The dynamic prompt is the execution engine's view of the graph; lookups happen constantly during topo-sort and cache validation, so this indicates the graph state and the request disagree.

Source

Thrown at comfy_execution/graph.py:35

class NodeNotFoundError(Exception):
    pass

class DynamicPrompt:
    def __init__(self, original_prompt):
        # The original prompt provided by the user
        self.original_prompt = original_prompt
        # Any extra pieces of the graph created during execution
        self.ephemeral_prompt = {}
        self.ephemeral_parents = {}
        self.ephemeral_display = {}

    def get_node(self, node_id):
        if node_id in self.ephemeral_prompt:
            return self.ephemeral_prompt[node_id]
        if node_id in self.original_prompt:
            return self.original_prompt[node_id]
        raise NodeNotFoundError(f"Node {node_id} not found")

    def has_node(self, node_id):
        return node_id in self.original_prompt or node_id in self.ephemeral_prompt

    def add_ephemeral_node(self, node_id, node_info, parent_id, display_id):
        self.ephemeral_prompt[node_id] = node_info
        self.ephemeral_parents[node_id] = parent_id
        self.ephemeral_display[node_id] = display_id

    def get_real_node_id(self, node_id):
        while node_id in self.ephemeral_parents:
            node_id = self.ephemeral_parents[node_id]
        return node_id

    def get_parent_node_id(self, node_id):
        return self.ephemeral_parents.get(node_id, None)

    def get_display_node_id(self, node_id):

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Validate the prompt before queueing: every link target/source id must exist as a key in prompt dict (frontend does this; scripts often don't).
  2. Fix typos in node ids in hand-constructed API payloads.
  3. If using cached/mutated history prompts, rebuild the full prompt rather than surgically editing link ids.
  4. For custom-node authors calling get_node(), check has_node(id) first or keep ids from the same dynprompt generation.

Example fix

# before
prompt = {
  '1': {'class_type': 'KSampler', 'inputs': {'model': ['99', 0], ...}},  # node '99' absent
}

# after
prompt = {
  '1': {'class_type': 'KSampler', 'inputs': {'model': ['2', 0], ...}},
  '2': {'class_type': 'CheckpointLoaderSimple', 'inputs': {...}},
}
Defensive patterns

Strategy: validation

Validate before calling

def prompt_links_resolve(prompt: dict) -> bool:
    for node_id, node in prompt.items():
        for v in node.get('inputs', {}).values():
            if isinstance(v, list) and len(v) == 2 and isinstance(v[0], str):
                if v[0] not in prompt:
                    return False
    return True

Try / catch

from comfy_execution.graph import NodeNotFoundError
try:
    node = dynprompt.get_node(nid)
except NodeNotFoundError as e:
    logging.warning('stale node reference %s: %s', nid, e)
    return

Prevention

When it happens

Trigger: Execution machinery references a node id that was never queued: a malformed prompt JSON where an inputs link points at a nonexistent node id, a node deleted from the prompt between queueing and execution, or custom code calling dynprompt.get_node() with a stale id (e.g. from cached validation results).

Common situations: Hand-built prompt dicts (API users) with link arrays ["node_id", output_index] referencing a typo'd or omitted node; races where the frontend mutates the workflow while the queue processes it; custom nodes manipulating prompt structures; or clients resubmitting a partially-patched prompt from history.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/00e1700d0f53b7a8. Report an issue: GitHub.