Skip to content
Latchkey

Vitest vi.mock factory hoisting ReferenceError in CI

Vitest hoists vi.mock to the top of the file, above your imports and variable declarations. If the mock factory closes over an outer variable, that variable is not initialized yet when the factory runs, so it throws.

What this error means

A test fails at load with "ReferenceError: Cannot access 'X' before initialization" pointing at a vi.mock factory that references a const or import declared lower in the file.

Vitest output
ReferenceError: Cannot access 'mockFn' before initialization

 ❯ src/service.test.ts:3:24
      2| const mockFn = vi.fn();
      3| vi.mock('./api', () => ({ fetchUser: mockFn }));
       |                          ^

Common causes

The factory references a hoisted-over variable

Because vi.mock is moved above the file body, any outer const/import it uses is in the temporal dead zone when the factory executes.

A top-level mock value not wrapped in vi.hoisted

Values the factory needs were declared normally instead of through vi.hoisted, so they are not available at hoist time.

How to fix it

Declare shared values with vi.hoisted

  1. Wrap variables the factory needs in vi.hoisted so they are initialized before the mock runs.
  2. Reference the hoisted object from inside the factory.
  3. Re-run so the mock initializes cleanly.
service.test.ts
const { mockFn } = vi.hoisted(() => ({ mockFn: vi.fn() }));
vi.mock('./api', () => ({ fetchUser: mockFn }));

Or define the mock inline

If the factory needs no outer reference, define everything inside it so nothing is hoisted over.

service.test.ts
vi.mock('./api', () => ({ fetchUser: vi.fn() }));

How to prevent it

  • Use vi.hoisted for any value a mock factory must reference.
  • Keep mock factories self-contained where possible.
  • Remember vi.mock runs before the rest of the module body.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →