jestjs/jest · error · Error

${matcherHintFromConfig(...)} Snapshot state must be initia

Error message

${matcherHintFromConfig(...)}

Snapshot state must be initialized

${printWithType('Snapshot state', snapshotState, stringify)}

What it means

Thrown by `_toMatchSnapshot` (index.ts:303-312) when the matcher's `context.snapshotState` is `null`/`undefined`. `SnapshotState` is created per test file by Jest's runner and threaded into the matcher context; a missing state means the matcher was invoked outside Jest's snapshot lifecycle (or the runner failed to initialize it).

Source

Thrown at packages/jest-snapshot/src/index.ts:307

  const {currentConcurrentTestName, isNot, snapshotState} = context;
  const currentTestName =
    currentConcurrentTestName?.() ?? context.currentTestName;

  if (isNot) {
    throw new Error(
      matcherErrorMessage(
        matcherHintFromConfig(config, false),
        NOT_SNAPSHOT_MATCHERS,
      ),
    );
  }

  if (snapshotState == null) {
    // Because the state is the problem, this is not a matcher error.
    // Call generic stringify from jest-matcher-utils package
    // because uninitialized snapshot state does not need snapshot serializers.
    throw new Error(
      `${matcherHintFromConfig(config, false)}\n\n` +
        'Snapshot state must be initialized' +
        `\n\n${printWithType('Snapshot state', snapshotState, stringify)}`,
    );
  }

  const fullTestName =
    currentTestName && hint
      ? `${currentTestName}: ${hint}`
      : currentTestName || ''; // future BREAKING change: || hint

  if (typeof properties === 'object') {
    if (typeof received !== 'object' || received === null) {
      throw new Error(
        matcherErrorMessage(
          matcherHintFromConfig(config, false),
          `${RECEIVED_COLOR(
            'received',

View on GitHub (pinned to f49721c78e)

Solutions

  1. Use `toMatchSnapshot` only inside real Jest test files so the runner sets up `snapshotState`.
  2. If invoking programmatically, construct a `SnapshotState` (from `jest-snapshot`) and attach it to the matcher context before calling.
  3. Switch to a non-snapshot assertion (`toEqual`, `toBe`) for contexts where snapshot state isn't available.

Example fix

// before — outside Jest
const { toMatchSnapshot } = require('jest-snapshot');
toMatchSnapshot.call({ isNot: false }, value); // snapshotState missing

// after — provide a SnapshotState
const { SnapshotState } = require('jest-snapshot');
const state = new SnapshotState('/tmp/x.snap', { update: 'all', ... });
toMatchSnapshot.call({ isNot: false, snapshotState: state }, value);
Defensive patterns

Strategy: validation

Validate before calling

if (!context || !context.snapshotState) {
  throw new Error('SnapshotState not initialized; run inside a Jest test or construct one.');
}
expect(x).toMatchSnapshot();

Type guard

function hasSnapshotState(ctx: unknown): ctx is { snapshotState: import('jest-snapshot').SnapshotState } {
  return !!ctx && typeof ctx === 'object' && 'snapshotState' in ctx && !!(ctx as any).snapshotState;
}

Prevention

When it happens

Trigger: Invoking `toMatchSnapshot` outside a real Jest test (e.g. extracted into a script that calls the matcher directly), or calling it before `SnapshotState` is attached to the context. Custom runners that don't set up `snapshotState`.

Common situations: Unit-testing the matcher in isolation. Custom test frameworks reusing Jest matchers without bootstrapping `SnapshotState`. Race conditions in custom runners.

Related errors


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