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
- Use a valid identifier suffix, e.g. `{ suffix: 'Promised' }` or 'Async'.
- Validate the suffix with a regex like /^[A-Za-z_$][\w$]*$/ before passing it.
- 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
- Keep suffixes alphanumeric camelCase identifiers ('Async', 'Promised').
- Validate user/config-provided suffixes against an identifier regex.
- Omit the suffix option to accept the default.
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.