{"record":{"id":"4c1eda77d384f48c","repo":"nodejs/node","slug":"und-err-invalid-arg-4c1eda","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-agent.js","lineNumber":45,"sourceCode":"const Dispatcher = require('../dispatcher/dispatcher')\nconst PendingInterceptorsFormatter = require('./pending-interceptors-formatter')\nconst { MockCallHistory } = require('./mock-call-history')\n\nclass MockAgent extends Dispatcher {\n  constructor (opts = {}) {\n    super(opts)\n\n    const mockOptions = buildAndValidateMockOptions(opts)\n\n    this[kNetConnect] = true\n    this[kIsMockActive] = true\n    this[kMockAgentIsCallHistoryEnabled] = mockOptions.enableCallHistory ?? false\n    this[kMockAgentAcceptsNonStandardSearchParameters] = mockOptions.acceptNonStandardSearchParameters ?? false\n    this[kIgnoreTrailingSlash] = mockOptions.ignoreTrailingSlash ?? false\n\n    // Instantiate Agent and encapsulate\n    if (opts?.agent && typeof opts.agent.dispatch !== 'function') {\n      throw new InvalidArgumentError('Argument opts.agent must implement Agent')\n    }\n    const agent = opts?.agent ? opts.agent : new Agent(opts)\n    this[kAgent] = agent\n\n    this[kClients] = agent[kClients]\n    this[kOptions] = mockOptions\n\n    if (this[kMockAgentIsCallHistoryEnabled]) {\n      this[kMockAgentRegisterCallHistory]()\n    }\n  }\n\n  get (origin) {\n    // Normalize origin to handle URL objects and case-insensitive hostnames\n    const normalizedOrigin = normalizeOrigin(origin)\n    const originKey = this[kIgnoreTrailingSlash] ? normalizedOrigin.replace(/\\/$/, '') : normalizedOrigin\n\n    let dispatcher = this[kMockAgentGet](originKey)","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/mock/mock-agent.js#L27-L63","documentation":"Thrown by the `MockAgent` constructor (`InvalidArgumentError`, code `UND_ERR_INVALID_ARG`) when `opts.agent` is provided but does not expose a `dispatch` function. `MockAgent` wraps a real dispatcher (defaulting to a new `Agent`) and routes intercepted dispatches through it for non-mocked origins; it probes the supplied object for `dispatch` to confirm it is a Dispatcher-compatible agent. Anything lacking that method cannot be delegated to.","triggerScenarios":"Passing `agent: new URL(...)`, an options object, a plain `{ connections: 10 }` (the opts, not an agent), or a custom object that forgot to implement `dispatch`. The guard is `opts?.agent && typeof opts.agent.dispatch !== 'function'`. Note the check is duck-typed on the `dispatch` method, not on `instanceof Agent`.","commonSituations":"Passing the agent options object where the agent instance belongs; wrapping a custom Dispatcher subclass that did not expose `dispatch`; passing a Proxy agent or Pool where the consumer expected an Agent; copy-paste from examples that use a different variable name.","solutions":["Pass an actual undici `Agent` (or any object exposing `dispatch(opts, handler)`), e.g. `new MockAgent({ agent: existingAgent })`.","If you only want to configure the underlying agent, pass those options directly to `MockAgent` and let it construct the inner `Agent` itself.","For custom dispatchers, ensure they expose a `dispatch` method matching the Dispatcher contract."],"exampleFix":"// before\nconst agent = new MockAgent({ agent: { connections: 10 } })\nconst agent = new MockAgent({ agent: somePool }) // no dispatch\n\n// after\nconst agent = new MockAgent({ agent: new Agent({ connections: 10 }) })\n// or let MockAgent build it:\nconst agent = new MockAgent({ connections: 10 })","handlingStrategy":"type-guard","validationCode":"function resolveAgent(candidate) {\n  if (candidate == null) return undefined\n  if (typeof candidate.dispatch !== 'function') {\n    throw new Error('opts.agent must expose a dispatch(opts, handler) function')\n  }\n  return candidate\n}","typeGuard":"function isDispatcherLike(v) {\n  return v != null && typeof v.dispatch === 'function'\n}","tryCatchPattern":null,"preventionTips":["Pass an Agent instance, not an options object.","Let MockAgent build the inner agent when you only need to configure it.","Duck-type on dispatch, not instanceof, for custom dispatchers."],"tags":["undici","mock","mock-agent","dispatcher","validation","config"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}