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
- Fix the dependency array to reference only keys that exist in the tasks object
- Check for typos between task keys and dependency names
- Log the generated tasks object keys before calling async.auto when building graphs dynamically
- 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
- Keep task keys and dependency names in a shared constant object
- Lint for typos by extracting keys and deps before calling auto
- Write a unit test that validates the graph shape for dynamically built tasks
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
- async.auto cannot execute tasks due to a recursive dependenc
- autoInject task functions require explicit parameters.
- expected a function
- could not parse args in autoInject Source: ${src}
- arity is undefined
AI-assisted analysis of caolan/async@13dfaf13f3 (2026-08-28).
Data as JSON: /api/errors/da88ee30318cedd4.
Report an issue: GitHub.