{"record":{"id":"6fc9b2afe8efa1e9","repo":"vitest-dev/vitest","slug":"expect-poll-must-be-called-inside-a-test","errorCode":null,"errorMessage":"expect.poll() must be called inside a test","messagePattern":"expect\\.poll\\(\\) must be called inside a test","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/integrations/chai/poll.ts","lineNumber":67,"sourceCode":"    const state = getWorkerState()\n    const defaults = state.config.expect?.poll ?? {}\n    const {\n      interval = defaults.interval ?? 50,\n      timeout = defaults.timeout ?? 1000,\n      message,\n    } = options\n    // @ts-expect-error private poll access\n    const assertion = expect(null, message).withContext({\n      poll: true,\n    }) as Assertion\n    fn = fn.bind(assertion)\n    // injected so that domain snapshot can take over poll implementation.\n    chai.util.flag(assertion, '_poll.fn', fn)\n    chai.util.flag(assertion, '_poll.timeout', timeout)\n    chai.util.flag(assertion, '_poll.interval', interval)\n    const test = chai.util.flag(assertion, 'vitest-test') as Test | undefined\n    if (!test) {\n      throw new Error('expect.poll() must be called inside a test')\n    }\n    const proxy: any = new Proxy(assertion, {\n      get(target, key, receiver) {\n        const assertionFunction = Reflect.get(target, key, receiver)\n\n        if (typeof assertionFunction !== 'function') {\n          return assertionFunction instanceof chai.Assertion ? proxy : assertionFunction\n        }\n\n        if (key === 'assert') {\n          return assertionFunction\n        }\n\n        if (typeof key === 'string' && unsupported.includes(key)) {\n          throw new SyntaxError(\n            `expect.poll() is not supported in combination with .${key}(). Use vi.waitFor() if your assertion condition is unstable.`,\n          )\n        }","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/integrations/chai/poll.ts#L49-L85","documentation":"expect.poll() wraps an unstable assertion in a retry loop and needs the current Test context (set via the chai 'vitest-test' flag) to hook into test lifecycle (onFinished, timeout). If that flag is undefined — meaning poll() was called outside any running test — it throws immediately. Common when poll is used at module top level or inside a beforeAll/beforeEach hook rather than inside the test body.","triggerScenarios":"Calling expect.poll(fn).toBeX() outside of an `it`/`test` callback — e.g. in a beforeAll, at module scope, or in a standalone script. Also if the chai assertion context was not properly initialized with the test flag.","commonSituations":"Moving an assertion into a setup hook by mistake; calling expect.poll during module import; using expect.poll in a helper that is invoked outside a test boundary.","solutions":["Move the expect.poll call inside an `it`/`test` callback body.","If polling logic is needed in setup, use vi.waitFor or vi.waitUntil instead which do not require the test assertion context.","Ensure custom assertion wrappers forward the chai context so the vitest-test flag is preserved."],"exampleFix":"// before — poll called in beforeAll:\nbeforeAll(() => { await expect.poll(() => getStatus()).toBe('ready') })\n\n// after — poll called inside the test:\nit('waits', async () => { await expect.poll(() => getStatus()).toBe('ready') })","handlingStrategy":"validation","validationCode":"// ensure you are inside a test callback before using expect.poll:\n// move the call into it(...)/test(...), not beforeAll/beforeEach/module scope","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep expect.poll calls inside it/test bodies only.","Use vi.waitFor for setup-time polling conditions."],"tags":["expect","poll","lifecycle","assertion"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}