{"record":{"id":"0a2db21e1b5df8a8","repo":"vitest-dev/vitest","slug":"vi-when-no-behavior-defined-when-called-with-a","errorCode":null,"errorMessage":"vi.when: no behavior defined when called with [${args.map(arg => stringify(arg)).join(', ')}]","messagePattern":"vi\\.when: no behavior defined when called with \\[(.+?)\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/integrations/mock/when.ts","lineNumber":330,"sourceCode":"      if (equals(args, behavior.arguments, testers)) {\n        return behavior.actions.findLast(action => !(action.remaining === 0 && action.called)) ?? null\n      }\n    }\n\n    return null\n  }\n\n  spy.mockImplementation(\n    // @ts-expect-error cannot resolve generic args\n    (...args: ScopedParameters) => {\n      const action = findAction(args)\n\n      if (action === null) {\n        const onUnmatched = typeof options?.onUnmatched === 'function'\n          ? options.onUnmatched\n          : options?.onUnmatched === 'throw'\n            ? () => {\n                throw new Error(`vi.when: no behavior defined when called with [${args.map(arg => stringify(arg)).join(', ')}]`)\n              }\n            : originalImplementation\n        return onUnmatched?.(...args)\n      }\n\n      action.remaining -= 1\n      action.called = true\n\n      switch (action.type) {\n        case 'return': {\n          return action.value\n        }\n\n        case 'throw': {\n          throw action.value\n        }\n\n        case 'resolve': {","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/integrations/mock/when.ts#L312-L348","documentation":"Thrown at call-time by a mock configured with `vi.when(spy, { onUnmatched: 'throw' })` when the mock is invoked with arguments that match no registered `calledWith(...)` behavior. It is not raised for default `onUnmatched` (which falls back to the original implementation); it only fires when the caller explicitly opts into throwing on unmatched calls. The message echoes the received arguments.","triggerScenarios":"Setting up `vi.when(spy, { onUnmatched: 'throw' }).calledWith(1).thenReturn('a')` and then calling `spy(2)` (or any arg set not registered). Also triggered by partial matches where equality testers (custom testers, `iterableEquality`) decide the args don't match a behavior.","commonSituations":"Strict-mocking every call site; a refactor that adds a new call path not yet stubbed; argument shape changes (e.g. extra property) that make previously-matching args unequal; flaky tests where call order varies.","solutions":["Register a behavior for the actual argument set with another `.calledWith(...)` chain.","If falling back is acceptable, remove `{ onUnmatched: 'throw' }` (or set `onUnmatched` to the original implementation) so unmatched calls invoke the real function.","Use a custom `onUnmatched` function to log the call and return a sensible default for diagnosis."],"exampleFix":"// before\nconst spy = vi.fn()\nvi.when(spy, { onUnmatched: 'throw' }).calledWith(1).thenReturn('a')\nspy(2) // throws\n\n// after\nconst spy = vi.fn()\nvi.when(spy, { onUnmatched: 'throw' })\n  .calledWith(1).thenReturn('a')\n  .calledWith(2).thenReturn('b')\nspy(2) // 'b'","handlingStrategy":"fallback","validationCode":"// before setting onUnmatched: 'throw', register a catch-all behavior\nvi.when(spy).calledWith(expect.anything()).thenReturn('default')\nvi.when(spy, { onUnmatched: 'throw' }).calledWith(1).thenReturn('a')","typeGuard":null,"tryCatchPattern":"try {\n  spy(unexpectedArg)\n} catch (e) {\n  if (e instanceof Error && /no behavior defined/.test(e.message)) {\n    // register the missing behavior or relax onUnmatched\n  }\n  throw e\n}","preventionTips":["Register behaviors for every realistic call path before enabling onUnmatched: 'throw'.","Use a custom onUnmatched function that logs unmatched calls during test development.","When argument shapes change, update calledWith matchers alongside the production code."],"tags":["vi-when","onunmatched","mocking","strict-mocking"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}