caolan/async · error · Error
Invalid arguments for async.retry
Error message
Invalid arguments for async.retry
What it means
async.retry() throws 'Invalid arguments for async.retry' when the task argument passed as the last positional argument is not a function. The library expects retry(task, [opts], [callback]) where task is the function to re-attempt; anything else (undefined, an object, a string) cannot be wrapped by wrapAsync and is rejected eagerly. This is an argument-validation error designed to fail fast instead of crashing later inside the retry loop.
Source
Thrown at lib/retry.js:113
const DEFAULT_TIMES = 5;
const DEFAULT_INTERVAL = 0;
export default function retry(opts, task, callback) {
var options = {
times: DEFAULT_TIMES,
intervalFunc: constant(DEFAULT_INTERVAL)
};
if (arguments.length < 3 && typeof opts === 'function') {
callback = task || promiseCallback();
task = opts;
} else {
parseTimes(options, opts);
callback = callback || promiseCallback();
}
if (typeof task !== 'function') {
throw new Error("Invalid arguments for async.retry");
}
var _task = wrapAsync(task);
var attempt = 1;
function retryAttempt() {
_task((err, ...args) => {
if (err === false) return
if (err && attempt++ < options.times &&
(typeof options.errorFilter != 'function' ||
options.errorFilter(err))) {
setTimeout(retryAttempt, options.intervalFunc(attempt - 1));
} else {
callback(err, ...args);
}
});
}
View on GitHub (pinned to 13dfaf13f3)
Solutions
- Ensure the last argument passed to async.retry is the task function to run
- Check the task variable is defined and typeof === 'function' before calling retry
- Correct the argument order: retry(timesOrOpts, task, callback) — do not omit the task
- If using promises, pass an async function, not a Promise instance
Example fix
// before
async.retry({times: 3}, taskConfig); // taskConfig is not a function
// after
async.retry({times: 3}, fetchWithBackoff, function(err, result) { ... }); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof task !== 'function') { throw new TypeError('retry: task must be a function, got ' + typeof task); } Type guard
function isTask(v) { return typeof v === 'function'; } Try / catch
try {
async.retry(opts, task, cb);
} catch (err) {
if (err.message.includes('Invalid arguments for async.retry')) {
console.error('retry task argument must be a function, got:', typeof task);
} else { throw err; }
} Prevention
- Always pass the task function as the last positional argument before the callback
- Assert typeof task === 'function' at module boundaries
- Use TypeScript signatures so missing/non-function tasks are caught at compile time
- Avoid passing Promises; wrap await-style code in an async function
When it happens
Trigger: Calling async.retry with a non-function as the task argument: async.retry(5, opts) where the function was forgotten, async.retry(options) with only an options object and no task, passing a variable that is undefined because the task function is misnamed or not yet imported, or passing a promise instead of a callback-style function.
Common situations: Refactoring that renamed the task function leaving a stale reference (undefined at call time); passing an async/await-style function wrapper object instead of a function; copy-pasted calls like async.retry({times: 3}, config) missing the actual worker; TypeScript/JS interop where an optional task defaults to undefined.
Related errors
- task callback must be a function
- expected a function
- async.auto task `${key}` has a non-existent dependency `${de
- async.auto cannot execute tasks due to a recursive dependenc
- could not parse args in autoInject Source: ${src}
AI-assisted analysis of caolan/async@13dfaf13f3 (2026-08-28).
Data as JSON: /api/errors/9ea5ed629795d31b.
Report an issue: GitHub.