{"id":"a23593129b58c08e","repo":"jestjs/jest","slug":"returning-a-promise-from-describe-is-not-support","errorCode":null,"errorMessage":"Returning a Promise from \"describe\" is not supported. Tests must be defined synchronously.","messagePattern":"Returning a Promise from \"describe\" is not supported\\. Tests must be defined synchronously\\.","errorType":"exception","errorClass":"ErrorWithStack","httpStatus":null,"severity":"error","filePath":"packages/jest-circus/src/index.ts","lineNumber":79,"sourceCode":"    throw asyncError;\n  }\n  try {\n    blockName = convertDescriptorToString(blockName);\n  } catch (error) {\n    asyncError.message = (error as Error).message;\n    throw asyncError;\n  }\n\n  dispatchSync({\n    asyncError,\n    blockName,\n    mode,\n    name: 'start_describe_definition',\n  });\n  const describeReturn = blockFn();\n\n  if (isPromise(describeReturn)) {\n    throw new ErrorWithStack(\n      'Returning a Promise from \"describe\" is not supported. Tests must be defined synchronously.',\n      describeFn,\n    );\n  } else if (describeReturn !== undefined) {\n    throw new ErrorWithStack(\n      'A \"describe\" callback must not return a value.',\n      describeFn,\n    );\n  }\n\n  dispatchSync({blockName, mode, name: 'finish_describe_definition'});\n};\n\nconst _addHook = (\n  fn: Circus.HookFn,\n  hookType: Circus.HookType,\n  hookFn: THook,\n  timeout?: number,","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-circus/src/index.ts#L61-L97","documentation":"jest-circus throws this when a describe() callback returns a Promise. describe blocks run synchronously during test collection (the tree is built before any test executes), so an async describe would mean the test tree is incomplete when Jest tries to run it. The guard at packages/jest-circus/src/index.ts:78 calls isPromise() on the callback's return value and throws an ErrorWithStack pointing at the describe function so the stack trace lands on the user's call site.","triggerScenarios":"Writing `describe('x', async () => { await db.connect(); it(...) })`, awaiting a top-level promise inside a describe body, or returning a thenable from describe (e.g. `describe('x', () => someAsyncFn())`). The check fires the moment the describe callback returns a thenable.","commonSituations":"Developers new to Jest assume describe is async-aware and try to do shared DB/container setup at the top of describe instead of in a hook. Migration from Mocha (which permits async describe in some setups) also surfaces this.","solutions":["Remove the `async` keyword from the describe callback and move the async setup into `beforeAll(async () => { ... })`; beforeAll/afterAll/test bodies ARE allowed to be async.","If you are returning a value unintentionally (e.g. an arrow shorthand `describe('x', () => setup())`), change to a block body `describe('x', () => { setup(); })` so nothing is returned.","Enable the `eslint-plugin-jest` rule `no-return-promise-in-describe` to catch this at lint time."],"exampleFix":"// before\ndescribe('users', async () => {\n  const db = await connectDb();\n  it('lists users', () => expect(db.list()).resolves.toEqual([]));\n});\n\n// after\ndescribe('users', () => {\n  let db;\n  beforeAll(async () => { db = await connectDb(); });\n  it('lists users', () => expect(db.list()).resolves.toEqual([]));\n});","handlingStrategy":"validation","validationCode":"// Before authoring, assert the describe callback is a non-async function.\nfunction assertSyncDescribe(fn: () => void): void {\n  if (fn.constructor?.name === 'AsyncFunction') {\n    throw new Error('describe callback must not be async; move async work into beforeAll');\n  }\n}\n// usage: assertSyncDescribe(() => { /* body */ }); describe('x', () => { /* body */ });","typeGuard":"const isPromise = (v: unknown): v is Promise<unknown> =>\n  v != null && typeof (v as any).then === 'function';","tryCatchPattern":null,"preventionTips":["Never mark a describe callback `async`; use beforeAll/beforeEach for async setup.","Use eslint-plugin-jest rule `no-return-promise-in-describe`.","Prefer block bodies for describe so no value is accidentally returned."],"tags":["jest-circus","async","describe","test-definition"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}