affaan-m/ECC · error · ValueError

Unknown workflow input

Error message

Unknown workflow input

What it means

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').

Solutions

  1. Add the missing key to the workflow's inputs object in the JSON
  2. Update the node reference to use an existing input key exactly as declared
  3. Ensure every 'input' reference has two elements: ['input', '<key>']
  4. Regenerate the workflow from load_graph's known kinds (apply, apply-motion, distill, prop3d) to get the canonical input names

Example fix

// before
{"inputs": {"image": "..."}, ..."fields": "{{input.latent}}"}
// after
{"inputs": {"image": "...", "latent": "..."}, ..."fields": "{{input.latent}}"}
Defensive patterns

Strategy: validation

Validate before calling

inputs = graph['inputs']
for node in graph['nodes'].values():
    for ref in re.findall(r"\{\{input\.(\w+)\}", json.dumps(node)):
        assert ref in inputs, f'unknown workflow input: {ref}'

Try / catch

try:
    graph = load_graph(kind)
except ValueError as e:
    if str(e) == 'Unknown workflow input':
        # check the workflow's inputs section vs referenced keys
        ...

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/45ca233ba6d3c177. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/workflow_graphs.py:103

    def visit(name, stack):
        if name == 'input':
            return set()
        if name in stack:
            raise ValueError('Dependency cycle')
        if name not in ancestors:
            deps = nodes[name].get('depends', [])
            ancestors[name] = set(deps).union(*(visit(dep, stack | {name}) for dep in deps))
        return ancestors[name]

    for name, node in nodes.items():
        reachable = visit(name, set())
        for ref in references_in({'input': node.get('input'), 'fields': node.get('fields')}):
            if ref[0] not in reachable:
                raise ValueError(f'{name} references undeclared dependency: {ref[0]}')
            if ref[0] == 'input':
                if len(ref) < 2 or ref[1] not in inputs:
                    raise ValueError('Unknown workflow input')
                used.add(ref[1])
    for ref in references_in(contents.get('output', {})):
        if ref[0] not in nodes:
            raise ValueError('Unknown output node')
    if used != set(inputs):
        raise ValueError(f'Unwired workflow inputs: {sorted(set(inputs) - used)}')


def load_graph(kind):
    if kind not in ('apply', 'apply-motion', 'distill', 'prop3d'):
        raise ValueError('Unknown workflow kind')
    graph = json.loads((WORKFLOWS / f'taste-{kind}.json').read_text())
    validate_graph(graph)
    return graph


def main():
    parser = argparse.ArgumentParser(description=__doc__)

View on GitHub (pinned to 8321021c54)