petkaantonov/bluebird · error · RangeError

suffix must be a valid identifier See http://goo.gl/Mqr

Error message

suffix must be a valid identifier

    See http://goo.gl/MqrFmX

What it means

`Promise.promisifyAll` validates that the `suffix` option is a valid JavaScript identifier (via `util.isIdentifier`) because it will generate method names like `readFileAsync` by concatenation. An invalid suffix throws a RangeError (SUFFIX_NOT_IDENTIFIER) at src/promisify.js:309.

Source

Thrown at src/promisify.js:309

    util.copyDescriptors(fn, ret, propsFilter);
    return ret;
};

Promise.promisifyAll = function (target, options) {
    if (typeof target !== "function" && typeof target !== "object") {
        throw new TypeError(PROMISIFY_TYPE_ERROR);
    }
    options = Object(options);
    var multiArgs = !!options.multiArgs;
    var suffix = options.suffix;
    if (typeof suffix !== "string") suffix = defaultSuffix;
    var filter = options.filter;
    if (typeof filter !== "function") filter = defaultFilter;
    var promisifier = options.promisifier;
    if (typeof promisifier !== "function") promisifier = makeNodePromisified;

    if (!util.isIdentifier(suffix)) {
        throw new RangeError(SUFFIX_NOT_IDENTIFIER);
    }

    var keys = util.inheritedDataKeys(target);
    for (var i = 0; i < keys.length; ++i) {
        var value = target[keys[i]];
        if (keys[i] !== "constructor" &&
            util.isClass(value)) {
            promisifyAll(value.prototype, suffix, filter, promisifier,
                multiArgs);
            promisifyAll(value, suffix, filter, promisifier, multiArgs);
        }
    }

    return promisifyAll(target, suffix, filter, promisifier, multiArgs);
};
};

View on GitHub (pinned to c220cfe480)

Solutions

  1. Use a valid identifier suffix, e.g. `{ suffix: 'Promised' }` or 'Async'.
  2. Validate the suffix with a regex like /^[A-Za-z_$][\w$]*$/ before passing it.
  3. Omit the suffix option entirely to use the default 'Async'.

Example fix

// before
Promise.promisifyAll(fs, { suffix: '-async' });
// after
Promise.promisifyAll(fs, { suffix: 'Async' });
Defensive patterns

Strategy: validation

Validate before calling

const IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
if (suffix !== undefined && !IDENT.test(suffix)) {
  throw new RangeError('suffix must be a valid identifier');
}
Promise.promisifyAll(target, { suffix });

Type guard

const isValidSuffix = (v) => typeof v === 'string' && /^[A-Za-z_$][\w$]*$/.test(v);

Try / catch

try { Promise.promisifyAll(target, { suffix }); } catch (e) {
  if (e instanceof RangeError) {
    target = Promise.promisifyAll(target); // default 'Async'
  } else throw e;
}

Prevention

When it happens

Trigger: `Promise.promisifyAll(obj, { suffix: '-promised' })` (hyphen invalid); suffix with spaces or starting with a digit; suffix accidentally set to null and coerced logic bypassed because it was passed explicitly as a non-string that somehow passed earlier checks.

Common situations: CLI/config supplied suffixes containing dashes; using empty string '' (not a valid identifier); generated suffixes from templates.

Related errors


AI-assisted analysis of petkaantonov/bluebird@c220cfe480 (2026-09-02). Data as JSON: /api/errors/4d69d23e873f8201. Report an issue: GitHub.