{"record":{"id":"da88ee30318cedd4","repo":"caolan/async","slug":"async-auto-task-key-has-a-non-existent-depend","errorCode":null,"errorMessage":"async.auto task `${key}` has a non-existent dependency `${dependencyName}` in ${dependencies.join(', ')}","messagePattern":"async\\.auto task `(.+?)` has a non-existent dependency `(.+?)` in (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/auto.js","lineNumber":200,"sourceCode":"        if (!Array.isArray(task)) {\n            // no dependencies\n            enqueueTask(key, [task]);\n            readyToCheck.push(key);\n            return;\n        }\n\n        var dependencies = task.slice(0, task.length - 1);\n        var remainingDependencies = dependencies.length;\n        if (remainingDependencies === 0) {\n            enqueueTask(key, task);\n            readyToCheck.push(key);\n            return;\n        }\n        uncheckedDependencies[key] = remainingDependencies;\n\n        dependencies.forEach(dependencyName => {\n            if (!tasks[dependencyName]) {\n                throw new Error('async.auto task `' + key +\n                    '` has a non-existent dependency `' +\n                    dependencyName + '` in ' +\n                    dependencies.join(', '));\n            }\n            addListener(dependencyName, () => {\n                remainingDependencies--;\n                if (remainingDependencies === 0) {\n                    enqueueTask(key, task);\n                }\n            });\n        });\n    });\n\n    checkForDeadlocks();\n    processQueue();\n\n    function enqueueTask(key, task) {\n        readyTasks.push(() => runTask(key, task));","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/caolan/async/blob/13dfaf13f3fc809ba1c9c39d5e267ac6959cbf4a/lib/auto.js#L182-L218","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nasync.auto({\n  read: ['fil', readFile],\n  data: ['read', processData]\n});\n// after\nasync.auto({\n  read: ['file', readFile],\n  data: ['read', processData]\n});","handlingStrategy":"validation","validationCode":"function validateAutoTasks(tasks) {\n  for (const [key, def] of Object.entries(tasks)) {\n    const deps = Array.isArray(def) ? def[0] : [];\n    for (const d of deps) {\n      if (!tasks[d]) throw new Error(`Task '${key}' depends on unknown task '${d}'`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await async.auto(tasks);\n} catch (err) {\n  if (String(err.message).includes('non-existent dependency')) {\n    console.error('Task graph misconfigured:', err.message);\n  } else throw err;\n}","preventionTips":["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"],"tags":["async","dependency-graph","validation"],"backgroundTag":"missing-dependency","analyzedSha":"13dfaf13f3fc809ba1c9c39d5e267ac6959cbf4a","analyzedAt":"2026-08-28T22:50:46.507Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}