{"id":"0be83599c62c621a","repo":"jestjs/jest","slug":"invalid-first-argument-descriptor-it-must-be","errorCode":null,"errorMessage":"Invalid first argument, ${descriptor}. It must be a named class, named function, number, or string.","messagePattern":"Invalid first argument, (.+?)\\. It must be a named class, named function, number, or string\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-util/src/convertDescriptorToString.ts","lineNumber":28,"sourceCode":"export default function convertDescriptorToString(\n  descriptor: Global.BlockNameLike | undefined,\n): string {\n  switch (typeof descriptor) {\n    case 'function':\n      if (descriptor.name) {\n        return descriptor.name;\n      }\n      break;\n\n    case 'number':\n    case 'undefined':\n      return `${descriptor}`;\n\n    case 'string':\n      return descriptor;\n  }\n\n  throw new Error(\n    `Invalid first argument, ${descriptor}. It must be a named class, named function, number, or string.`,\n  );\n}\n","sourceCodeStart":10,"sourceCodeEnd":32,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-util/src/convertDescriptorToString.ts#L10-L32","documentation":"Thrown by `convertDescriptorToString` (convertDescriptorToString.ts:28-30) when the first argument to a `describe`/`it`/`test` block (the block name) cannot be coerced to a string. The function accepts named functions (uses `.name`), numbers, strings, and undefined; everything else - booleans, symbols, objects, arrays, and anonymous functions (whose `.name` is empty) - falls through to the throw.","triggerScenarios":"Calling `describe({}, fn)`, `describe(true, fn)`, `describe(Symbol(), fn)`, `describe([], fn)`, or `describe(() => {}, fn)` (anonymous arrow -> `descriptor.name` is `''` -> falsy -> throw). Also `describe(someObject, fn)`.","commonSituations":"Passing a variable that was expected to be a string but is an object/boolean; using an anonymous arrow as a describe name expecting it to stringify; copy-paste errors where a name was forgotten; destructuring mistakes producing undefined that then gets default-but-typed weirdly.","solutions":["Pass a literal string (or a named function whose `.name` you intend) as the first argument to `describe`/`it`/`test`.","If using a function as the name, give it a name (`function myScope() {}`) so `.name` is non-empty.","Add a guard before the call to coerce unknown descriptor values: `typeof name === 'string' ? name : String(name)`."],"exampleFix":"// before\ndescribe(() => {}, () => { it('works', () => {}); });\n// after\ndescribe('my module', () => { it('works', () => {}); });","handlingStrategy":"validation","validationCode":"function validName(d) {\n  const t = typeof d;\n  return t === 'string' || t === 'number' || (t === 'function' && !!d.name);\n}\nif (!validName(descriptor)) throw new Error('pass a string/number/named-function name');","typeGuard":"const isValidBlockName = (d: unknown): boolean =>\n  typeof d === 'string' || typeof d === 'number' || (typeof d === 'function' && d.name.length > 0);","tryCatchPattern":null,"preventionTips":["Always pass a literal string as the describe/it name.","If passing a function, name it (`function billing() {}`) - anonymous arrows have empty `.name`.","Avoid spreading objects/booleans into describe names."],"tags":["jest-util","test-name","user-error","type-error"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}