caolan/async · error · Error

autoInject task functions require explicit parameters.

Error message

autoInject task functions require explicit parameters.

What it means

autoInject infers dependencies from parameter names; a task function with zero parameters gives it nothing to infer. When the function has length 0, is not detected as an async-style function, and parsing also yields no params, autoInject throws because the task would be unusable. This catches forgetting to declare dependencies/callback entirely.

Source

Thrown at lib/autoInject.js:156

        var taskFn = tasks[key]
        var params;
        var fnIsAsync = isAsync(taskFn);
        var hasNoDeps =
            (!fnIsAsync && taskFn.length === 1) ||
            (fnIsAsync && taskFn.length === 0);

        if (Array.isArray(taskFn)) {
            params = [...taskFn];
            taskFn = params.pop();

            newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
        } else if (hasNoDeps) {
            // no dependencies, use the function as-is
            newTasks[key] = taskFn;
        } else {
            params = parseParams(taskFn);
            if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {
                throw new Error("autoInject task functions require explicit parameters.");
            }

            // remove callback param
            if (!fnIsAsync) params.pop();

            newTasks[key] = params.concat(newTask);
        }

        function newTask(results, taskCb) {
            var newArgs = params.map(name => results[name])
            newArgs.push(taskCb);
            wrapAsync(taskFn)(...newArgs);
        }
    });

    return auto(newTasks, callback);
}

View on GitHub (pinned to 13dfaf13f3)

Solutions

  1. Add explicit parameters (the callback at minimum): (callback) => ...
  2. Declare dependencies as named parameters, e.g. (data, callback) => ...
  3. Use an async function or arrow returning a promise so fnIsAsync is true
  4. Use async.auto with explicit dependency arrays instead

Example fix

// before
autoInject({ task: () => doWork() });
// after
autoInject({ task: async () => { return doWork(); } });
// or
autoInject({ task: (callback) => doWork(callback) });
Defensive patterns

Strategy: validation

Validate before calling

function assertAutoInjectTask(fn) {
  if (fn.length === 0 && !/^\s*async\s/.test(fn.toString()) &&
      !(fn instanceof (async function(){}).constructor)) {
    throw new Error('autoInject task must declare params (deps and/or callback)');
  }
}

Try / catch

try {
  await autoInject(tasks);
} catch (err) {
  if (String(err.message).includes('require explicit parameters')) {
    console.error('Add a callback or make the task async');
  } else throw err;
}

Prevention

When it happens

Trigger: autoInject({task: () => {...}}) or autoInject({task: function() {...}}) — a task declared with an empty parameter list that also doesn't match known async signatures (e.g. not an async function or returning a promise).

Common situations: Converting code from async.auto to autoInject and dropping the callback parameter, writing a no-arg task that actually needs the completion callback, TypeScript arrow functions compiled to parameterless forms.

Related errors


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