affaan-m/ECC · error · ValueError

references undeclared dependency

Error message

{name} references undeclared dependency: {ref[0]}

What it means

validate_graph collects every field/input reference in a node (via references_in) and requires each referenced source to be inside the node's transitive depends set (reachable). If a reference names a node that is not a (transitive) dependency, the node would read data the graph never provides, so ValueError is raised.

Solutions

  1. Add the referenced node's name to the consuming node's depends array in the workflow JSON
  2. Check spelling of the reference against the exact node keys in nodes
  3. If the reference is transitively available, verify each intermediate edge is present in depends chains
  4. Remove the stale reference if the data is no longer needed

Example fix

// before
{"name": "apply", "depends": ["upscale"], "input": "{{distill.output}}"}
// after
{"name": "apply", "depends": ["upscale", "distill"], "input": "{{distill.output}}"}
Defensive patterns

Strategy: validation

Validate before calling

def deps_declared(node, nodes):
    reachable = set()
    stack = [node['name']]
    while stack:
        n = stack.pop()
        for d in nodes[n].get('depends', []):
            if d not in reachable:
                reachable.add(d); stack.append(d)
    refs = re.findall(r"\{\{(\w+)\.", json.dumps(node))
    return all(r in reachable for r in refs)

Try / catch

try:
    graph = load_graph(kind)
except ValueError as e:
    if 'references undeclared dependency' in str(e):
        node, ref = ...  # parse names from message
        graph['nodes'][node]['depends'].append(ref)

Prevention

When it happens

Trigger: A node's input/fields entries reference e.g. ['distill','embedding'] while the node's depends array omits 'distill' (or omits an intermediate node through which it would be reachable).

Common situations: Adding a reference to another node's output but forgetting to add that node to depends; removing a depends entry while leaving the references; typos in node names in references.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

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

            if dependency != 'input' and dependency not in nodes:
                raise ValueError(f'Unknown dependency: {dependency}')
    ancestors = {}

    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

View on GitHub (pinned to 8321021c54)