{"id":"5b5086719a23e149","repo":"jestjs/jest","slug":"key-has-to-be-of-type-string-or-number","errorCode":null,"errorMessage":"${key} has to be of type string or number","messagePattern":"(.+?) has to be of type string or number","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"packages/jest-validate/src/validate.ts","lineNumber":57,"sourceCode":"      typeof options.deprecate === 'function'\n    ) {\n      const isDeprecatedKey = options.deprecate(\n        config,\n        key,\n        options.deprecatedConfig,\n        options,\n      );\n\n      hasDeprecationWarnings = hasDeprecationWarnings || isDeprecatedKey;\n    } else if (allowsMultipleTypes(key)) {\n      const value = config[key];\n\n      if (\n        typeof options.condition === 'function' &&\n        typeof options.error === 'function'\n      ) {\n        if (key === 'maxWorkers' && !isOfTypeStringOrNumber(value)) {\n          throw new ValidationError(\n            'Validation Error',\n            `${key} has to be of type string or number`,\n            'maxWorkers=50% or\\nmaxWorkers=3',\n          );\n        }\n      }\n    } else if (Object.hasOwnProperty.call(exampleConfig, key)) {\n      if (\n        typeof options.condition === 'function' &&\n        typeof options.error === 'function' &&\n        !options.condition(config[key], exampleConfig[key])\n      ) {\n        options.error(key, config[key], exampleConfig[key], options, path);\n      }\n    } else if (\n      shouldSkipValidationForPath(path, key, options.recursiveDenylist)\n    ) {\n      // skip validating unknown options inside blacklisted paths","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-validate/src/validate.ts#L39-L75","documentation":"Thrown by `_validate` (validate.ts:56-62) as a special-case check for the `maxWorkers` config option. Because `maxWorkers` legitimately accepts multiple types (a number of workers, or a percentage string like `'50%'`), it bypasses the generic validator and is checked here: anything that is neither string nor number fails with the fixed example `maxWorkers=50%` or `maxWorkers=3`.","triggerScenarios":"Setting `maxWorkers` to a non-string-non-number value: a boolean (`maxWorkers: true`), an object, an array, `null`, or `undefined` propagated by accident. Numbers and strings (including `'50%'`) are accepted.","commonSituations":"Passing `--maxWorkers` via an env var that arrives as something unexpected; a config preset that sets `maxWorkers` conditionally and falls through to `null`; typos like `maxWorkers: { count: 4 }`.","solutions":["Set `maxWorkers` to a number (`maxWorkers: 4`) or a percentage string (`maxWorkers: '50%'`).","If deriving from env, coerce explicitly: `const mw = process.env.MW ? Number(process.env.MW) : '50%';`.","Avoid objects/booleans; if you need conditional behavior, branch in JS to pick a number or string."],"exampleFix":"// before\nmodule.exports = { maxWorkers: { count: 4 } }; // object - rejected\n// after\nmodule.exports = { maxWorkers: 4 };","handlingStrategy":"type-guard","validationCode":"const { getType } = require('@jest/get-type');\nif (['maxWorkers'].includes(key) && !['number','string'].includes(getType(value)))\n  throw new Error('maxWorkers must be a number or a string like \"50%\"');","typeGuard":"const isValidMaxWorkers = (v: unknown): boolean =>\n  typeof v === 'number' || typeof v === 'string';","tryCatchPattern":null,"preventionTips":["Set maxWorkers to a number or a percentage string only.","Coerce env-derived values explicitly (`Number(env) || '50%'`).","Never assign objects/booleans/arrays to maxWorkers."],"tags":["jest-validate","config","maxworkers","type-error","user-error"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}