{"record":{"id":"4d69d23e873f8201","repo":"petkaantonov/bluebird","slug":"suffix-must-be-a-valid-identifier-see-http","errorCode":null,"errorMessage":"suffix must be a valid identifier\n\n    See http://goo.gl/MqrFmX\n","messagePattern":"suffix must be a valid identifier\n\n    See http://goo\\.gl/MqrFmX\n","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"src/promisify.js","lineNumber":309,"sourceCode":"    util.copyDescriptors(fn, ret, propsFilter);\n    return ret;\n};\n\nPromise.promisifyAll = function (target, options) {\n    if (typeof target !== \"function\" && typeof target !== \"object\") {\n        throw new TypeError(PROMISIFY_TYPE_ERROR);\n    }\n    options = Object(options);\n    var multiArgs = !!options.multiArgs;\n    var suffix = options.suffix;\n    if (typeof suffix !== \"string\") suffix = defaultSuffix;\n    var filter = options.filter;\n    if (typeof filter !== \"function\") filter = defaultFilter;\n    var promisifier = options.promisifier;\n    if (typeof promisifier !== \"function\") promisifier = makeNodePromisified;\n\n    if (!util.isIdentifier(suffix)) {\n        throw new RangeError(SUFFIX_NOT_IDENTIFIER);\n    }\n\n    var keys = util.inheritedDataKeys(target);\n    for (var i = 0; i < keys.length; ++i) {\n        var value = target[keys[i]];\n        if (keys[i] !== \"constructor\" &&\n            util.isClass(value)) {\n            promisifyAll(value.prototype, suffix, filter, promisifier,\n                multiArgs);\n            promisifyAll(value, suffix, filter, promisifier, multiArgs);\n        }\n    }\n\n    return promisifyAll(target, suffix, filter, promisifier, multiArgs);\n};\n};\n\n","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/petkaantonov/bluebird/blob/c220cfe480868e2f5c5de4fe8bb3b04b97588d7f/src/promisify.js#L291-L327","documentation":"`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.","triggerScenarios":"`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.","commonSituations":"CLI/config supplied suffixes containing dashes; using empty string '' (not a valid identifier); generated suffixes from templates.","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'."],"exampleFix":"// before\nPromise.promisifyAll(fs, { suffix: '-async' });\n// after\nPromise.promisifyAll(fs, { suffix: 'Async' });","handlingStrategy":"validation","validationCode":"const IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nif (suffix !== undefined && !IDENT.test(suffix)) {\n  throw new RangeError('suffix must be a valid identifier');\n}\nPromise.promisifyAll(target, { suffix });","typeGuard":"const isValidSuffix = (v) => typeof v === 'string' && /^[A-Za-z_$][\\w$]*$/.test(v);","tryCatchPattern":"try { Promise.promisifyAll(target, { suffix }); } catch (e) {\n  if (e instanceof RangeError) {\n    target = Promise.promisifyAll(target); // default 'Async'\n  } else throw e;\n}","preventionTips":["Keep suffixes alphanumeric camelCase identifiers ('Async', 'Promised').","Validate user/config-provided suffixes against an identifier regex.","Omit the suffix option to accept the default."],"tags":["rangeerror","promisifyall","options-validation"],"backgroundTag":"invalid-identifier-suffix","analyzedSha":"c220cfe480868e2f5c5de4fe8bb3b04b97588d7f","analyzedAt":"2026-09-02T02:30:20.863Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}