Comfy-Org/ComfyUI · error · NodeInputError
Node {to_node_id} says it needs input {to_input}, but that v
Error message
Node {to_node_id} says it needs input {to_input}, but that value is a constant What it means
Raised as NodeInputError by TopologicalSort.make_input_strong_link() in comfy_execution/graph.py when the named input exists in the node's prompt 'inputs' but holds a constant value instead of a link. Strong links only make sense between nodes (link format is [from_node_id, from_socket], detected by is_link()); a widget value like a number or string cannot participate, so the engine refuses rather than fabricate a dependency.
Source
Thrown at comfy_execution/graph.py:126
self.dynprompt = dynprompt
self.pendingNodes = {}
self.blockCount = {} # Number of nodes this node is directly blocked by
self.blocking = {} # Which nodes are blocked by this node
self.externalBlocks = 0
self.unblockedEvent = asyncio.Event()
def get_input_info(self, unique_id, input_name):
class_type = self.dynprompt.get_node(unique_id)["class_type"]
class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
return get_input_info(class_def, input_name)
def make_input_strong_link(self, to_node_id, to_input):
inputs = self.dynprompt.get_node(to_node_id)["inputs"]
if to_input not in inputs:
raise NodeInputError(f"Node {to_node_id} says it needs input {to_input}, but there is no input to that node at all")
value = inputs[to_input]
if not is_link(value):
raise NodeInputError(f"Node {to_node_id} says it needs input {to_input}, but that value is a constant")
from_node_id, from_socket = value
self.add_strong_link(from_node_id, from_socket, to_node_id)
def add_strong_link(self, from_node_id, from_socket, to_node_id):
if not self.is_cached(from_node_id):
self.add_node(from_node_id)
if to_node_id not in self.blocking[from_node_id]:
self.blocking[from_node_id][to_node_id] = {}
self.blockCount[to_node_id] += 1
self.blocking[from_node_id][to_node_id][from_socket] = True
def add_node(self, node_unique_id, include_lazy=False, subgraph_nodes=None):
node_ids = [node_unique_id]
links = []
while len(node_ids) > 0:
unique_id = node_ids.pop()
if unique_id in self.pendingNodes:View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Right-click the input on the target node and 'Convert widget to input', then connect the upstream node so the value arrives as a link.
- If you own the node, only declare strong dependencies for inputs that are meaningfully linkable, or tolerate constants by skipping the strong-link request.
- Rebuild the connection from the node the dependency expects (e.g. a primitive/seed node).
- Update or roll back the custom node pack if a new version made a formerly optional input mandatory.
Example fix
# before: prompt has a constant where a link is required
{'3': {'class_type': 'KSampler', 'inputs': {'seed': 42, ...}}}
# and node 3 declares a strong dependency on 'seed'
# after: route the value through a node
{'2': {'class_type': 'PrimitiveNode', 'inputs': {}},
'3': {'class_type': 'KSampler', 'inputs': {'seed': ['2', 0], ...}}} Defensive patterns
Strategy: type-guard
Validate before calling
def is_link(v) -> bool:
return isinstance(v, list) and len(v) == 2 and isinstance(v[0], (str, int)) and isinstance(v[1], int)
if not is_link(prompt[nid]['inputs'][input_name]):
raise ValueError(f'{input_name!r} must be connected to a node, not a constant') Type guard
def is_link(v) -> bool:
return isinstance(v, list) and len(v) == 2 and isinstance(v[0], (str, int)) and isinstance(v[1], int) Try / catch
from comfy_execution.graph import NodeInputError
try:
make_input_strong_link(nid, name)
except NodeInputError as e:
raise UserVisibleError(f'Convert {name!r} to a node input: {e}') from e Prevention
- Convert widgets to inputs (right-click node) for any field a node declares as a dependency.
- Node authors: only request strong links for link-capable inputs.
- After updating node packs, re-check workflows that use widget constants on dependency inputs.
When it happens
Trigger: A node declares a strong dependency on an input (via CHECK_REQUIREMENTS / lazy input resolution) but the workflow has that input connected to a widget constant — e.g. 'seed' or 'denoise' typed directly instead of fed from another node. The dependency machinery calls make_input_strong_link, finds 1.0 or 'text' instead of a link array, and raises.
Common situations: Users convert a widget to input only when convenient and leave a constant where a node implementation now requires an upstream node (common with seeds fed from a 'seed generator' node or context nodes); custom nodes adding hard requirements to previously-constant inputs; workflows shared between users where one side used input conversion.
Related errors
- Node {to_node_id} says it needs input {to_input}, but there
- Node {node_id} not found
- This Controlnet needs a VAE but none was provided, please us
- Need at least {require_count} hooks to combine, but only had
- Bad block_type
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/324cbec05283eac2.
Report an issue: GitHub.