{"record":{"id":"2d1a1fd9d31d6520","repo":"nodejs/node","slug":"und-err-invalid-arg-2d1a1f","errorCode":"UND_ERR_INVALID_ARG","errorMessage":"Argument opts.agent must implement Agent","messagePattern":"Argument opts\\.agent must implement Agent","errorType":"validation","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/mock/mock-client.js","lineNumber":26,"sourceCode":"  kMockAgent,\n  kClose,\n  kOriginalClose,\n  kOrigin,\n  kOriginalDispatch,\n  kConnected,\n  kIgnoreTrailingSlash\n} = require('./mock-symbols')\nconst { MockInterceptor } = require('./mock-interceptor')\nconst Symbols = require('../core/symbols')\nconst { InvalidArgumentError } = require('../core/errors')\n\n/**\n * MockClient provides an API that extends the Client to influence the mockDispatches.\n */\nclass MockClient extends Client {\n  constructor (origin, opts) {\n    if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') {\n      throw new InvalidArgumentError('Argument opts.agent must implement Agent')\n    }\n\n    super(origin, opts)\n\n    this[kMockAgent] = opts.agent\n    this[kOrigin] = origin\n    this[kIgnoreTrailingSlash] = opts.ignoreTrailingSlash ?? false\n    this[kDispatches] = []\n    this[kConnected] = 1\n    this[kOriginalDispatch] = this.dispatch\n    this[kOriginalClose] = this.close.bind(this)\n\n    this.dispatch = buildMockDispatch.call(this)\n    this.close = this[kClose]\n  }\n\n  get [Symbols.kConnected] () {\n    return this[kConnected]","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/mock/mock-client.js#L8-L44","documentation":"Thrown by the MockClient constructor when opts is missing, opts.agent is missing, or opts.agent.dispatch is not a function. MockClient extends Client and needs the parent MockAgent to delegate unmatched dispatches and share state, so the agent must look like an Agent (duck-typed on dispatch).","triggerScenarios":"Constructing `new MockClient(origin)` with no opts, with opts that omit agent, or passing a plain object/custom agent that has no dispatch method. Most commonly hit when instantiating MockClient directly instead of obtaining it via mockAgent.get(origin).","commonSituations":"Manually new-ing MockClient for a test instead of using MockAgent.get(); passing a real undici Agent/Pool where a MockAgent was expected; refactoring that drops the agent option.","solutions":["Obtain a MockClient through the MockAgent: const client = mockAgent.get('http://localhost:3000').","If constructing manually, pass the MockAgent: new MockClient(origin, { agent: mockAgent }).","Ensure the passed agent is a real MockAgent instance (it exposes dispatch)."],"exampleFix":"// before\nconst client = new MockClient('http://localhost:3000')\n\n// after\nconst mockAgent = new MockAgent()\nconst client = mockAgent.get('http://localhost:3000')\n// or\nconst client = new MockClient('http://localhost:3000', { agent: mockAgent })","handlingStrategy":"validation","validationCode":"function getMockClient(mockAgent, origin) {\n  if (!mockAgent || typeof mockAgent.dispatch !== 'function') {\n    throw new TypeError('Provide a MockAgent instance');\n  }\n  return mockAgent.get(origin);\n}","typeGuard":"function isAgentLike(v) {\n  return v != null && typeof v.dispatch === 'function';\n}","tryCatchPattern":null,"preventionTips":["Obtain MockClient via mockAgent.get(origin) instead of new MockClient(...).","Always pass { agent: mockAgent } when constructing manually.","Keep a single shared MockAgent instance and reuse it across test setup."],"tags":["undici","mock","validation","constructor","agent"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}