jestjs/jest · error · Error
Jest: concurrent test "${specFullName}" must return a Promis
Error message
Jest: concurrent test "${specFullName}" must return a Promise. What it means
Thrown inside `makeConcurrent` in jasmineAsyncInstall.ts:220 when a concurrent test function (`it.concurrent`/`test.concurrent`/`fit.concurrent`/`it.concurrent.only`/`skip`) is invoked and its return value is not a Promise. Concurrent tests are scheduled through a `pLimit` mutex that awaits the returned promise, so a synchronous or void return cannot be queued.
Source
Thrown at packages/jest-jasmine2/src/jasmineAsyncInstall.ts:220
const concurrentFn = function (
specName: Global.TestNameLike,
fn: Global.ConcurrentTestFn,
timeout?: number,
) {
let promise: Promise<unknown> = Promise.resolve();
const spec = originalFn.call(env, specName, () => promise, timeout);
if (env != null && !env.specFilter(spec)) {
return spec;
}
try {
promise = mutex(() => {
const promise = fn();
if (isPromise(promise)) {
return promise;
}
throw new Error(
`Jest: concurrent test "${spec.getFullName()}" must return a Promise.`,
);
});
} catch (error) {
promise = Promise.reject(error);
}
// Avoid triggering the uncaught promise rejection handler in case the test errors before
// being awaited on.
// eslint-disable-next-line @typescript-eslint/no-empty-function
promise.catch(() => {});
return spec;
};
// eslint-disable-next-line unicorn/consistent-function-scoping
const failing = () => {
throw new Error(
'Jest: `failing` tests are only supported in `jest-circus`.',View on GitHub (pinned to f49721c78e)
Solutions
- Mark the concurrent test body `async`: `it.concurrent('x', async () => { ... })`.
- Ensure an explicit `return promise` if the body is not `async`.
- If the work is genuinely synchronous, use plain `it` instead of `it.concurrent`.
Example fix
// before
it.concurrent('syncs users', () => { syncUsers(); });
// after
it.concurrent('syncs users', async () => { await syncUsers(); }); Defensive patterns
Strategy: validation
Validate before calling
const wrapped = async () => { /* ... */ };
it.concurrent('x', wrapped); // wrapped is provably async Type guard
const returnsPromise = (fn: (...a: any[]) => any): boolean => fn.constructor.name === 'AsyncFunction' || true; // best: ensure `async` keyword
Prevention
- Always declare concurrent test bodies with `async`.
- Reserve it.concurrent for genuinely asynchronous work; use it for sync tests.
When it happens
Trigger: Writing `it.concurrent('x', () => { doSyncStuff(); })`, `it.concurrent('x', () => { return 42; })`, or `it.concurrent('x', (done) => { done(); })` — none return a Promise.
Common situations: Treating `it.concurrent` like `it` (which allows non-Promise returns); converting a callback-style test to concurrent without making it async; forgetting `async` on the test body.
Related errors
- received value must be a promise or a function returning a p
- Missing second argument. It must be a callback function. Per
- Invalid second argument, ${fn}. It must be a callback functi
- Jest: `failing` tests are only supported in `jest-circus`.
- received value must be a number
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/1c4f480948c1cd19.json.
Report an issue: GitHub.