{"id":"108672be86643374","repo":"vitest-dev/vitest","slug":"snapshot-cannot-be-used-outside-of-test","errorCode":null,"errorMessage":"Snapshot cannot be used outside of test","messagePattern":"Snapshot cannot be used outside of test","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/snapshot/src/client.ts","lineNumber":134,"sourceCode":"\n  match(options: AssertOptions): MatchResult {\n    const {\n      filepath,\n      name,\n      testId = name,\n      message,\n      isInline = false,\n      properties,\n      inlineSnapshot,\n      error,\n      errorMessage,\n      rawSnapshot,\n      assertionName,\n    } = options\n    let { received } = options\n\n    if (!filepath) {\n      throw new Error('Snapshot cannot be used outside of test')\n    }\n\n    const snapshotState = this.getSnapshotState(filepath)\n    const testName = [name, ...(message ? [message] : [])].join(' > ')\n\n    // Probe first so we can mark as checked even on early return\n    const expectedSnapshot = snapshotState.probeExpectedSnapshot({\n      testName,\n      testId,\n      isInline,\n      inlineSnapshot,\n    })\n\n    if (typeof properties === 'object') {\n      if (typeof received !== 'object' || !received) {\n        expectedSnapshot.markAsChecked()\n        throw new Error(\n          'Received value must be an object when the matcher has properties',","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/snapshot/src/client.ts#L116-L152","documentation":"Thrown by SnapshotClient.match() when the filepath option is falsy. Vitest derives filepath from the running test's task context, so a missing filepath means the snapshot assertion executed without an active test (e.g. at module top level, inside a worker that isn't a test, or via a hand-rolled SnapshotClient with no setup() call). The library refuses to write or compare a snapshot because it has nowhere to persist it and no test lifecycle to attach it to.","triggerScenarios":"Calling expect(x).toMatchSnapshot() (or toMatchInlineSnapshot / toThrowErrorMatchingSnapshot) outside of an it/test/it.each callback; constructing a SnapshotClient directly and calling client.match({ filepath: '', ... }); running an assertion in a setup file, afterAll, or a bare script that Vitest does not register as a test module.","commonSituations":"Hoisting expect().toMatchSnapshot() to module scope by mistake; calling snapshot assertions inside describe body instead of inside it(); using the snapshot client in a non-Vitest runner without calling client.setup(filepath, options) first; refactoring that moved an assertion out of a test function.","solutions":["Move the expect(...).toMatchSnapshot() call inside an it() or test() callback so Vitest can bind the current test's filepath.","If you are using SnapshotClient directly, call await client.setup(filepath, options) and pass a non-empty filepath into match().","Check that the file is being collected as a test file (matches test.include) and is not loaded as a regular module.","Ensure the assertion is not running in a hook (beforeAll/afterAll) or at top level where there is no current task."],"exampleFix":"// before\nimport { expect } from 'vitest'\nexpect({ a: 1 }).toMatchInlineSnapshot()\n\n// after\nimport { expect, test } from 'vitest'\ntest('snapshot', () => {\n  expect({ a: 1 }).toMatchInlineSnapshot()\n})","handlingStrategy":"validation","validationCode":"import { getCurrentTest } from '@vitest/runner'\n\nif (getCurrentTest()) {\n  expect(value).toMatchSnapshot()\n} else {\n  // not in a test — skip or assert in a different way\n}","typeGuard":"import type { Task } from 'vitest'\nfunction insideTest(t: unknown): t is Task {\n  return typeof t === 'object' && t !== null && 'id' in t && 'name' in t\n}","tryCatchPattern":null,"preventionTips":["Always place snapshot assertions inside it()/test() callbacks, never at module scope or inside describe() body.","If using SnapshotClient directly, gate every call on a non-empty filepath and a prior setup().","Lint for expect(...).toMatch* calls outside of test blocks via an eslint-plugin-vitest rule."],"tags":["snapshot","test-context","configuration"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}