{"record":{"id":"324cbec05283eac2","repo":"Comfy-Org/ComfyUI","slug":"node-to-node-id-says-it-needs-input-to-input-324cbe","errorCode":null,"errorMessage":"Node {to_node_id} says it needs input {to_input}, but that value is a constant","messagePattern":"Node (.+?) says it needs input (.+?), but that value is a constant","errorType":"exception","errorClass":"NodeInputError","httpStatus":null,"severity":"error","filePath":"comfy_execution/graph.py","lineNumber":126,"sourceCode":"        self.dynprompt = dynprompt\n        self.pendingNodes = {}\n        self.blockCount = {} # Number of nodes this node is directly blocked by\n        self.blocking = {} # Which nodes are blocked by this node\n        self.externalBlocks = 0\n        self.unblockedEvent = asyncio.Event()\n\n    def get_input_info(self, unique_id, input_name):\n        class_type = self.dynprompt.get_node(unique_id)[\"class_type\"]\n        class_def = nodes.NODE_CLASS_MAPPINGS[class_type]\n        return get_input_info(class_def, input_name)\n\n    def make_input_strong_link(self, to_node_id, to_input):\n        inputs = self.dynprompt.get_node(to_node_id)[\"inputs\"]\n        if to_input not in inputs:\n            raise NodeInputError(f\"Node {to_node_id} says it needs input {to_input}, but there is no input to that node at all\")\n        value = inputs[to_input]\n        if not is_link(value):\n            raise NodeInputError(f\"Node {to_node_id} says it needs input {to_input}, but that value is a constant\")\n        from_node_id, from_socket = value\n        self.add_strong_link(from_node_id, from_socket, to_node_id)\n\n    def add_strong_link(self, from_node_id, from_socket, to_node_id):\n        if not self.is_cached(from_node_id):\n            self.add_node(from_node_id)\n            if to_node_id not in self.blocking[from_node_id]:\n                self.blocking[from_node_id][to_node_id] = {}\n                self.blockCount[to_node_id] += 1\n            self.blocking[from_node_id][to_node_id][from_socket] = True\n\n    def add_node(self, node_unique_id, include_lazy=False, subgraph_nodes=None):\n        node_ids = [node_unique_id]\n        links = []\n\n        while len(node_ids) > 0:\n            unique_id = node_ids.pop()\n            if unique_id in self.pendingNodes:","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_execution/graph.py#L108-L144","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: prompt has a constant where a link is required\n{'3': {'class_type': 'KSampler', 'inputs': {'seed': 42, ...}}}\n# and node 3 declares a strong dependency on 'seed'\n\n# after: route the value through a node\n{'2': {'class_type': 'PrimitiveNode', 'inputs': {}},\n '3': {'class_type': 'KSampler', 'inputs': {'seed': ['2', 0], ...}}}","handlingStrategy":"type-guard","validationCode":"def is_link(v) -> bool:\n    return isinstance(v, list) and len(v) == 2 and isinstance(v[0], (str, int)) and isinstance(v[1], int)\n\nif not is_link(prompt[nid]['inputs'][input_name]):\n    raise ValueError(f'{input_name!r} must be connected to a node, not a constant')","typeGuard":"def is_link(v) -> bool:\n    return isinstance(v, list) and len(v) == 2 and isinstance(v[0], (str, int)) and isinstance(v[1], int)","tryCatchPattern":"from comfy_execution.graph import NodeInputError\ntry:\n    make_input_strong_link(nid, name)\nexcept NodeInputError as e:\n    raise UserVisibleError(f'Convert {name!r} to a node input: {e}') from e","preventionTips":["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."],"tags":["execution","graph","custom-nodes","workflow"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}