{"record":{"id":"45ca233ba6d3c177","repo":"affaan-m/ECC","slug":"unknown-workflow-input","errorCode":null,"errorMessage":"Unknown workflow input","messagePattern":"Unknown workflow input","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/workflow_graphs.py","lineNumber":103,"sourceCode":"\n    def visit(name, stack):\n        if name == 'input':\n            return set()\n        if name in stack:\n            raise ValueError('Dependency cycle')\n        if name not in ancestors:\n            deps = nodes[name].get('depends', [])\n            ancestors[name] = set(deps).union(*(visit(dep, stack | {name}) for dep in deps))\n        return ancestors[name]\n\n    for name, node in nodes.items():\n        reachable = visit(name, set())\n        for ref in references_in({'input': node.get('input'), 'fields': node.get('fields')}):\n            if ref[0] not in reachable:\n                raise ValueError(f'{name} references undeclared dependency: {ref[0]}')\n            if ref[0] == 'input':\n                if len(ref) < 2 or ref[1] not in inputs:\n                    raise ValueError('Unknown workflow input')\n                used.add(ref[1])\n    for ref in references_in(contents.get('output', {})):\n        if ref[0] not in nodes:\n            raise ValueError('Unknown output node')\n    if used != set(inputs):\n        raise ValueError(f'Unwired workflow inputs: {sorted(set(inputs) - used)}')\n\n\ndef load_graph(kind):\n    if kind not in ('apply', 'apply-motion', 'distill', 'prop3d'):\n        raise ValueError('Unknown workflow kind')\n    graph = json.loads((WORKFLOWS / f'taste-{kind}.json').read_text())\n    validate_graph(graph)\n    return graph\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=__doc__)","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/workflow_graphs.py#L85-L121","documentation":"When a node references the pseudo-node 'input', the second element must name a key declared in the workflow's top-level inputs object. If the reference lacks the key or the key is not declared, validate_graph raises ValueError('Unknown workflow input').","triggerScenarios":"A node input like ['input','image'] where 'image' is absent from the graph's inputs map, or a bare ['input'] reference with no key element.","commonSituations":"Renaming an input in the workflow inputs section without updating node references; copying nodes from a workflow with different input names; omitting the input key entirely.","solutions":["Add the missing key to the workflow's inputs object in the JSON","Update the node reference to use an existing input key exactly as declared","Ensure every 'input' reference has two elements: ['input', '<key>']","Regenerate the workflow from load_graph's known kinds (apply, apply-motion, distill, prop3d) to get the canonical input names"],"exampleFix":"// before\n{\"inputs\": {\"image\": \"...\"}, ...\"fields\": \"{{input.latent}}\"}\n// after\n{\"inputs\": {\"image\": \"...\", \"latent\": \"...\"}, ...\"fields\": \"{{input.latent}}\"}","handlingStrategy":"validation","validationCode":"inputs = graph['inputs']\nfor node in graph['nodes'].values():\n    for ref in re.findall(r\"\\{\\{input\\.(\\w+)\\}\", json.dumps(node)):\n        assert ref in inputs, f'unknown workflow input: {ref}'","typeGuard":null,"tryCatchPattern":"try:\n    graph = load_graph(kind)\nexcept ValueError as e:\n    if str(e) == 'Unknown workflow input':\n        # check the workflow's inputs section vs referenced keys\n        ...","preventionTips":["Keep input names in a single constants list shared by inputs and node references","Rename inputs via search-and-replace across the whole workflow file","Validate workflow JSON in CI before deployment"],"tags":["graph","configuration","input-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}