jestjs/jest · error · ErrorWithStack
Todo must be called with only a description.
Error message
Todo must be called with only a description.
What it means
todo() creates a test placeholder and must be called with exactly one string argument — the description. Env.ts:591-598 throws (via ErrorWithStack, preserving a callsite) when the argument count is not 1 or the description is not a string, because a todo carries no body and any extra/missing data is a misuse.
Source
Thrown at packages/jest-jasmine2/src/jasmine/Env.ts:594
if (currentSpec !== null) {
throw new Error(
`Tests cannot be nested. Test "${spec.description}" cannot run because it is nested within "${currentSpec.description}".`,
);
}
currentDeclarationSuite.addChild(spec);
return spec;
};
this.xit = function (...args) {
const spec = this.it.apply(this, args);
spec.pend('Temporarily disabled with xit');
return spec;
};
this.todo = function () {
const description = arguments[0];
if (arguments.length !== 1 || typeof description !== 'string') {
throw new ErrorWithStack(
'Todo must be called with only a description.',
this.todo,
);
}
const spec = specFactory(
description,
// eslint-disable-next-line @typescript-eslint/no-empty-function
() => {},
currentDeclarationSuite,
);
if (currentDeclarationSuite.markedPending) {
spec.pend();
} else {
spec.todo();
}
currentDeclarationSuite.addChild(spec);
return spec;View on GitHub (pinned to f49721c78e)
Solutions
- Call todo with exactly one string: it.todo('description').
- If you actually want a body, use it('description', () => {...}) and later mark it skip, or use it.skip.
- If you have a parameterized placeholder, create one todo per row.
Example fix
// before — todo with a body (misuse)
it.todo('not yet done', () => { /* ... */ });
// after — pure placeholder
it.todo('not yet done'); Defensive patterns
Strategy: type-guard
Validate before calling
function assertTodoArgs(args: [unknown]) {
if (args.length !== 1 || typeof args[0] !== 'string') {
throw new Error('it.todo takes exactly one string description');
}
} Type guard
function isTodoArg(args: [unknown]): args is [string] {
return args.length === 1 && typeof args[0] === 'string';
} Prevention
- Remember it.todo takes ONLY a title — no callback, no options.
- Use it('title', fn) (or it.skip) when you need a body.
When it happens
Trigger: Calling `it.todo()` (no arg), `it.todo('a', fn)` (extra arg), or `it.todo(42)` (non-string). The check at Env.ts:593 (`arguments.length !== 1 || typeof description !== 'string'`) fires ErrorWithStack at line 594.
Common situations: Writing `it.todo('name', () => {...})` thinking todo takes a body; passing a template literal that evaluates to undefined; chaining todo like a normal it with options.
Related errors
- Missing second argument. It must be a callback function. Per
- Invalid second argument, ${fn}. It must be a callback functi
- Tests cannot be nested. Test "${spec.description}" cannot ru
- Missing second argument. It must be a callback function.
- Invalid second argument, ${specDefinitions}. It must be a ca
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/bea3e706b1e1bba5.json.
Report an issue: GitHub.