caolan/async · error · Error

async.auto task `${key}` has a non-existent dependency `${de

Error message

async.auto task `${key}` has a non-existent dependency `${dependencyName}` in ${dependencies.join(', ')}

What it means

async.auto validates every dependency name listed in a task's dependency array against the tasks object. If a task declares a dependency that was never defined, auto throws immediately before running any task. This is an upfront graph validation to fail fast rather than deadlock or silently skip.

Source

Thrown at lib/auto.js:200

        if (!Array.isArray(task)) {
            // no dependencies
            enqueueTask(key, [task]);
            readyToCheck.push(key);
            return;
        }

        var dependencies = task.slice(0, task.length - 1);
        var remainingDependencies = dependencies.length;
        if (remainingDependencies === 0) {
            enqueueTask(key, task);
            readyToCheck.push(key);
            return;
        }
        uncheckedDependencies[key] = remainingDependencies;

        dependencies.forEach(dependencyName => {
            if (!tasks[dependencyName]) {
                throw new Error('async.auto task `' + key +
                    '` has a non-existent dependency `' +
                    dependencyName + '` in ' +
                    dependencies.join(', '));
            }
            addListener(dependencyName, () => {
                remainingDependencies--;
                if (remainingDependencies === 0) {
                    enqueueTask(key, task);
                }
            });
        });
    });

    checkForDeadlocks();
    processQueue();

    function enqueueTask(key, task) {
        readyTasks.push(() => runTask(key, task));

View on GitHub (pinned to 13dfaf13f3)

Solutions

  1. Fix the dependency array to reference only keys that exist in the tasks object
  2. Check for typos between task keys and dependency names
  3. Log the generated tasks object keys before calling async.auto when building graphs dynamically
  4. If the dependency is optional, remove it and coordinate ordering another way

Example fix

// before
async.auto({
  read: ['fil', readFile],
  data: ['read', processData]
});
// after
async.auto({
  read: ['file', readFile],
  data: ['read', processData]
});
Defensive patterns

Strategy: validation

Validate before calling

function validateAutoTasks(tasks) {
  for (const [key, def] of Object.entries(tasks)) {
    const deps = Array.isArray(def) ? def[0] : [];
    for (const d of deps) {
      if (!tasks[d]) throw new Error(`Task '${key}' depends on unknown task '${d}'`);
    }
  }
}

Try / catch

try {
  await async.auto(tasks);
} catch (err) {
  if (String(err.message).includes('non-existent dependency')) {
    console.error('Task graph misconfigured:', err.message);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling async.auto({a: ['b', fn], b: fn2}) where task 'a' depends on 'b' but the dependency array contains a misspelled or undefined name, e.g. async.auto({read: ['fil', readFileFn]}) instead of 'file'. Also occurs when tasks are generated dynamically and a name is dropped.

Common situations: Typo in dependency names, renaming a task key without updating dependents, building the task graph from config where a step was removed, copy-paste between auto definitions.

Related errors


AI-assisted analysis of caolan/async@13dfaf13f3 (2026-08-28). Data as JSON: /api/errors/da88ee30318cedd4. Report an issue: GitHub.