caolan/async · error · Error

arity is undefined

Error message

arity is undefined

What it means

awaitify wraps a callback-style function so it can return a promise when no callback is supplied. It derives the callback position from arity; if the passed arity argument is falsy AND asyncFn.length is 0, there is no way to know where the callback belongs, so it throws. This guards against wrapping functions that declare no parameters.

Source

Thrown at lib/internal/awaitify.js:5

// conditionally promisify a function.
// only return a promise if a callback is omitted
export default function awaitify (asyncFn, arity) {
    if (!arity) arity = asyncFn.length;
    if (!arity) throw new Error('arity is undefined')
    function awaitable (...args) {
        if (typeof args[arity - 1] === 'function') {
            return asyncFn.apply(this, args)
        }

        return new Promise((resolve, reject) => {
            args[arity - 1] = (err, ...cbArgs) => {
                if (err) return reject(err)
                resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0])
            }
            asyncFn.apply(this, args)
        })
    }

    return awaitable
}

View on GitHub (pinned to 13dfaf13f3)

Solutions

  1. Declare the callback as a named parameter so asyncFn.length is > 0: function (callback) {...}
  2. Wrap the function to expose correct arity: const wrapped = (cb) => original(cb)
  3. Upgrade async (newer versions handle rest-arg functions better)
  4. Call the callback-taking function directly instead of via promisification

Example fix

// before
const fn = (...args) => legacy(...args); // length 0
// after
const fn = (callback) => legacy(callback); // length 1
Defensive patterns

Strategy: type-guard

Validate before calling

const isPromisifiable = (fn) => typeof fn === 'function' && fn.length > 0;

Type guard

function hasCallbackArity(fn) {
  return typeof fn === 'function' && fn.length > 0;
}

Try / catch

try {
  const promisified = awaitify(fn);
} catch (err) {
  if (String(err.message) === 'arity is undefined') {
    console.error('Function must declare a callback parameter');
  } else throw err;
}

Prevention

When it happens

Trigger: Internally when a wrapped function has zero declared parameters (e.g. (...args) => {} rest-only functions have length 0) and no explicit arity is given, e.g. a task function written as function (...args) {} passed to a promisified API.

Common situations: Using rest-parameter task functions with async promisification, minified functions compiled to rest args, passing a wrapper around the real callback-taking function.

Related errors


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