{"id":"e4f6733187030be1","repo":"vitest-dev/vitest","slug":"getassertionname-obj-cannot-be-used-without","errorCode":null,"errorMessage":"'${getAssertionName(obj)}' cannot be used without test context","messagePattern":"'(.+?)' cannot be used without test context","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/integrations/snapshot/chai.ts","lineNumber":68,"sourceCode":"  return {\n    filepath: test.file.filepath,\n    name: getNames(test).slice(1).join(' > '),\n    testId: test.id,\n  }\n}\n\nfunction getAssertionName(assertion: Chai.Assertion): string {\n  const name = chai.util.flag(assertion, '_name') as string | undefined\n  if (!name) {\n    throw new Error('Assertion name is not set. This is a bug in Vitest. Please, open a new issue with reproduction.')\n  }\n  return name\n}\n\nfunction getTest(obj: Chai.Assertion) {\n  const test = chai.util.flag(obj, 'vitest-test') as Test | undefined\n  if (!test) {\n    throw new Error(`'${getAssertionName(obj)}' cannot be used without test context`)\n  }\n  if (test.fails) {\n    throw new TestSyntaxError(`'${getAssertionName(obj)}' cannot be used with 'test.fails'`)\n  }\n  return test\n}\n\nfunction validateAssertion(assertion: Chai.Assertion): void {\n  if (chai.util.flag(assertion, 'negate')) {\n    throw new Error(`${getAssertionName(assertion)} cannot be used with \"not\"`)\n  }\n}\n\nexport const SnapshotPlugin: ChaiPlugin = (chai, utils) => {\n  for (const key of ['matchSnapshot', 'toMatchSnapshot']) {\n    utils.addMethod(\n      chai.Assertion.prototype,\n      key,","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/integrations/snapshot/chai.ts#L50-L86","documentation":"Every snapshot matcher resolves the current `Test` via the `vitest-test` chai flag (through `getTest`) to obtain filepath, test id, and test name used as the snapshot key. If no test is bound — because the matcher runs outside any `it`/`test` — there is no context to key the snapshot against, so it throws `'<name>' cannot be used without test context`.","triggerScenarios":"Calling `toMatchSnapshot`/`toMatchInlineSnapshot`/`toMatchFileSnapshot`/`toThrowErrorMatchingSnapshot`/`toThrowErrorMatchingInlineSnapshot` (and the domain variants) at module top level, inside hooks, or in a standalone script with no active test.","commonSituations":"Hoisting a snapshot assertion into a helper invoked outside a test, or running the expect API outside the Vitest runner.","solutions":["Move the snapshot assertion inside an `it()`/`test()` body.","For setup-time checks, capture the value in the hook and assert on it inside the test.","If writing a custom matcher, ensure it is invoked from within a test so the context is present."],"exampleFix":"// before (module scope)\nconst data = loadData()\nexpect(data).toMatchSnapshot()\n// after\nit('matches snapshot', () => {\n  expect(loadData()).toMatchSnapshot()\n})","handlingStrategy":"validation","validationCode":"import { getWorkerState } from 'vitest'\nfunction assertInTest() {\n  if (!getWorkerState().current) throw new Error('snapshot matchers require an active test')\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Place `toMatchSnapshot`/`toMatchInlineSnapshot` only inside `it()`/`test()`.","Capture setup values in hooks and assert inside tests."],"tags":["snapshot","test-context","matcher","assertion"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}