jestjs/jest · error · Error
Tests cannot be nested. Test
Error message
Tests cannot be nested. Test "${spec.description}" cannot run because it is nested within "${currentSpec.description}". What it means
Jasmine builds the test tree during the describe phase, then executes specs. Calling `it(...)` inside another spec's body (an `it` callback) means the nested spec is created DURING execution, when `currentSpec` is already set — jasmine cannot run it and would silently skip it. Env.it detects `currentSpec !== null` at line 584 and throws this Error naming both the nested and the outer spec to make the misuse explicit.
Solutions
- Move the nested `it` out to the describe level so it is a sibling, not a child of the other spec.
- For dynamic case generation, use `describe.each` or generate the cases inside a `describe` (not an `it`).
- If you need sub-assertions inside a test, use multiple `expect()` calls rather than nested `it`.
Example fix
// before — nested it, throws at runtime
it('outer', () => {
it('inner', () => { expect(1).toBe(1); });
});
// after — siblings
describe('outer', () => {
it('inner', () => { expect(1).toBe(1); });
}); Defensive patterns
Strategy: validation
Validate before calling
// Static lint: forbid it() calls inside it() bodies. // Use eslint-plugin-jest rule: 'no-nested-tests' or a custom visitor // that errors when an `it`/`test` CallExpression appears inside another // `it`/`test` CallExpression's callback.
Prevention
- Register tests at the describe level, never inside an it body.
- Use describe.each or it.each for data-driven cases rather than loops in specs.
- Add an ESLint rule (eslint-plugin-jest) to catch nested test definitions.
When it happens
Trigger: Writing `it('outer', () => { it('inner', () => {}) })`. The check `currentSpec !== null` at Env.ts:584 is true because the outer spec is executing. The error includes both `spec.description` (inner) and `currentSpec.description` (outer).
Common situations: Coming from Mocha which historically allowed (then deprecated) nested tests; a helper that registers specs and is accidentally called from within a spec body rather than a describe body; a loop inside a spec that tries to generate cases dynamically.
Related errors
- Invalid second argument
- Missing second argument. It must be a callback function.
- Missing second argument. It must be a callback function…
- Todo must be called with only a description.
- Argument passed to callFake should be a function, got
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/fdf135df1aa18f03.
Report an issue: GitHub.
Appendix: source
Thrown at packages/jest-jasmine2/src/jasmine/Env.ts:585
if (typeof fn !== 'function') {
throw new TypeError(
`Invalid second argument, ${fn}. It must be a callback function.`,
);
}
const spec = specFactory(
description,
fn,
currentDeclarationSuite,
timeout,
);
if (currentDeclarationSuite.markedPending) {
spec.pend();
}
// When a test is defined inside another, jasmine will not run it.
// This check throws an error to warn the user about the edge-case.
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.',View on GitHub (pinned to 8e6d128e4a)