jestjs/jest · error · ErrorWithStack

Jest: `failing` tests are only supported in `jest-circus`.

Error message

Jest: `failing` tests are only supported in `jest-circus`.

What it means

The `it.failing` / `test.failing` API (a test expected to fail) is implemented only in jest-circus, the default modern runner. When jest-jasmine2 is the test runner, index.ts replaces `it.failing` with a function that throws ErrorWithStack on call, so a test author discovers immediately that failing is unsupported rather than the directive being silently ignored. Errors 108 and 109 are the same guard for the base and the `.each` variant.

Source

Thrown at packages/jest-jasmine2/src/index.ts:162

        // @ts-expect-error: `it` is `void` for some reason
        it.result.__callsite = stack;

        return it;
      };
      return wrapped as any as T;
    }

    environment.global.it = wrapIt(environment.global.it);
    environment.global.xit = wrapIt(environment.global.xit);
    environment.global.fit = wrapIt(environment.global.fit);
  }

  jasmineAsyncInstall(globalConfig, environment.global);

  installEach(environment);

  const failing = () => {
    throw new ErrorWithStack(
      'Jest: `failing` tests are only supported in `jest-circus`.',
      failing,
    );
  };

  failing.each = () => {
    throw new ErrorWithStack(
      'Jest: `failing` tests are only supported in `jest-circus`.',
      failing.each,
    );
  };

  environment.global.it.failing = failing;
  environment.global.fit.failing = failing;
  environment.global.xit.failing = failing;

  environment.global.test = environment.global.it;
  environment.global.it.only = environment.global.fit;

View on GitHub (pinned to f49721c78e)

Solutions

  1. Switch to the default runner jest-circus: remove the `testRunner: 'jest-jasmine2'` override (circus has been default since Jest 27).
  2. If you must stay on jasmine2, remove the `.failing` modifier and track the expected failure another way (it.skip plus a TODO).
  3. Verify your Jest version supports circus and that no config/tooling is re-pinning jasmine2.

Example fix

// before — jasmine2 runner + failing
testRunner: 'jest-jasmine2'
it.failing('not yet implemented', () => { expect(x).toBe(2); });

// after — default circus runner (remove the override)
// jest.config.js: delete the testRunner line
it.failing('not yet implemented', () => { expect(x).toBe(2); });
Defensive patterns

Strategy: validation

Validate before calling

// Detect failing-usage when jasmine2 is the runner
const usingJasmine2 = config.testRunner?.endsWith('jest-jasmine2');
if (usingJasmine2 && sourceUsesFailing(testSource)) {
  throw new Error('it.failing requires jest-circus; remove testRunner override or drop .failing.');
}
// (sourceUsesFailing would grep the test file for /it\.failing|test\.failing/)

Prevention

When it happens

Trigger: Using `jest-jasmine2` as the testRunner (legacy runner) and writing `it.failing('...', () => {...})`. index.ts:161-166 defines `failing` to throw, and line 175 assigns it to it.failing/fit.failing/xit.failing. Calling it.failing(...) triggers the throw at line 162.

Common situations: Migrating a codebase that adopted `it.failing`; an older Jest config pinned to jasmine2 via `testRunner: 'jest-jasmine2'`; sharing test files between projects with different runners; copy-pasting a circus-only test into a jasmine2 project.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/fee034d8943780e1.json. Report an issue: GitHub.