{"record":{"id":"f8e90275a0552c0d","repo":"ruvnet/ruflo","slug":"mock-was-called-with-unexpected-arguments-json","errorCode":null,"errorMessage":"Mock was called with unexpected arguments: ${JSON.stringify(call)}\\nAllowed: ${JSON.stringify(allowedCalls)}","messagePattern":"Mock was called with unexpected arguments: (.+?)\\\\nAllowed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/testing/src/helpers/assertion-helpers.ts","lineNumber":352,"sourceCode":"/**\n * Assert that a mock was only called with allowed arguments\n *\n * @example\n * assertOnlyCalledWithAllowed(mockFn, [['valid1'], ['valid2']]);\n */\nexport function assertOnlyCalledWithAllowed(\n  mock: Mock,\n  allowedCalls: unknown[][]\n): void {\n  const calls = mock.mock.calls;\n\n  for (const call of calls) {\n    const isAllowed = allowedCalls.some(\n      allowed => JSON.stringify(call) === JSON.stringify(allowed)\n    );\n\n    if (!isAllowed) {\n      throw new Error(\n        `Mock was called with unexpected arguments: ${JSON.stringify(call)}\\n` +\n        `Allowed: ${JSON.stringify(allowedCalls)}`\n      );\n    }\n  }\n}\n\n/**\n * Assert that an array contains elements in partial order\n *\n * @example\n * assertPartialOrder(events, [\n *   { type: 'Start' },\n *   { type: 'Process' },\n *   { type: 'End' },\n * ]);\n */\nexport function assertPartialOrder<T>(","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/testing/src/helpers/assertion-helpers.ts#L334-L370","documentation":"assertOnlyCalledWithAllowed() compares every recorded call of a mock against an allowlist using JSON.stringify equality; any call that does not exactly match an allowed argument array throws, printing the offending call and the whole allowlist. Equality is structural and order-sensitive, so argument order and extra arguments matter.","triggerScenarios":"The code under test invokes the mock with an extra argument, different order, or a value not in allowedCalls; optional parameters materializing as undefined changing the JSON; Dates or floats serializing differently than expected.","commonSituations":"Refactors adding a new parameter to a collaborator call; allowlists written from memory instead of from mock.mock.calls; non-JSON-safe values in arguments.","solutions":["Print mock.mock.calls first and build the allowlist from actual legitimate invocations","Update the test to cover the new legitimate call signature when a refactor added arguments","For unstable serializations (Date, NaN, class instances), match on extracted fields instead of raw JSON equality"],"exampleFix":"// before\nassertOnlyCalledWithAllowed(mockSave, [['user-1']]); // throws if code calls save('user-1', { upsert: true })\n\n// after\nassertOnlyCalledWithAllowed(mockSave, [['user-1'], ['user-1', { upsert: true }]]);","handlingStrategy":"validation","validationCode":"// Preview recorded calls before asserting\nconst calls = mock.mock.calls;\nconsole.log('recorded calls:', JSON.stringify(calls, null, 2));\nassertOnlyCalledWithAllowed(mock, allowedCalls);","typeGuard":"function allCallsAllowed(mock: Mock, allowedCalls: unknown[][]): boolean {\n  return mock.mock.calls.every(call =>\n    allowedCalls.some(a => JSON.stringify(call) === JSON.stringify(a))\n  );\n}","tryCatchPattern":null,"preventionTips":["Derive allowedCalls from a recording of one known-good run instead of hand-writing them","Type collaborator signatures so added arguments surface as compile errors","Avoid JSON-equality assertions on values with unstable serialization such as Date or undefined"],"tags":["testing","mocks","assertion","vitest"],"backgroundTag":"mock-invocation-mismatch","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}