jestjs/jest · error · Error
Invalid first argument, ${descriptor}. It must be a named cl
Error message
Invalid first argument, ${descriptor}. It must be a named class, named function, number, or string. What it means
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.
Source
Thrown at packages/jest-util/src/convertDescriptorToString.ts:28
export default function convertDescriptorToString(
descriptor: Global.BlockNameLike | undefined,
): string {
switch (typeof descriptor) {
case 'function':
if (descriptor.name) {
return descriptor.name;
}
break;
case 'number':
case 'undefined':
return `${descriptor}`;
case 'string':
return descriptor;
}
throw new Error(
`Invalid first argument, ${descriptor}. It must be a named class, named function, number, or string.`,
);
}
View on GitHub (pinned to f49721c78e)
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)`.
Example fix
// before
describe(() => {}, () => { it('works', () => {}); });
// after
describe('my module', () => { it('works', () => {}); }); Defensive patterns
Strategy: validation
Validate before calling
function validName(d) {
const t = typeof d;
return t === 'string' || t === 'number' || (t === 'function' && !!d.name);
}
if (!validName(descriptor)) throw new Error('pass a string/number/named-function name'); Type guard
const isValidBlockName = (d: unknown): boolean => typeof d === 'string' || typeof d === 'number' || (typeof d === 'function' && d.name.length > 0);
Prevention
- 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.
When it happens
Trigger: 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)`.
Common situations: 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.
Related errors
- Jest: Failed to load ESM at ${filePath} - did you use a defa
- Jest: requireOrImportModule path must be absolute, was "${fi
- Option "${path}.${option}" must be of type: ${validTyp
- ${key} has to be of type string or number
- @jest/diff-sequences: ${name} typeof ${typeof arg} is not a
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/0be83599c62c621a.json.
Report an issue: GitHub.