{"record":{"id":"ba47a7899fbbc26a","repo":"nodejs/node","slug":"factory-must-be-a-function","errorCode":null,"errorMessage":"factory must be a function.","messagePattern":"factory must be a function\\.","errorType":"exception","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/dispatcher/round-robin-pool.js","lineNumber":49,"sourceCode":"    connections,\n    factory = defaultFactory,\n    connect,\n    connectTimeout,\n    tls,\n    maxCachedSessions,\n    socketPath,\n    autoSelectFamily,\n    autoSelectFamilyAttemptTimeout,\n    allowH2,\n    clientTtl,\n    ...options\n  } = {}) {\n    if (connections != null && (!Number.isFinite(connections) || connections < 0)) {\n      throw new InvalidArgumentError('invalid connections')\n    }\n\n    if (typeof factory !== 'function') {\n      throw new InvalidArgumentError('factory must be a function.')\n    }\n\n    if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {\n      throw new InvalidArgumentError('connect must be a function or an object')\n    }\n\n    if (typeof connect !== 'function') {\n      connect = buildConnector({\n        ...tls,\n        maxCachedSessions,\n        allowH2,\n        socketPath,\n        timeout: connectTimeout,\n        ...(typeof autoSelectFamily === 'boolean' ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),\n        ...connect\n      })\n    }\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/dispatcher/round-robin-pool.js#L31-L67","documentation":"Thrown by the RoundRobinPool constructor when factory is not a function. RoundRobinPool relies on factory to instantiate each client it load-balances across; a non-callable factory cannot build clients. The guard matches Pool's: typeof factory !== 'function'.","triggerScenarios":"Passing factory as an object, string, or an already-constructed client instance. RoundRobinPool calls factory(origin, opts) per connection, so it needs the constructor reference, not a product.","commonSituations":"Passing new Client(url) (instance) instead of Client (class); importing the wrong symbol; JSON config that cannot carry functions; refactoring that wrapped the factory in an options bag.","solutions":["Pass the class/function reference: factory: (origin, opts) => new Client(origin, opts), or omit it for the default.","Do not pass a pre-built instance as factory.","Keep factory assignment in code, not in deserialized config.","If you only need custom sockets, set connect instead."],"exampleFix":"// before\nnew RoundRobinPool(url, { factory: new Client(url) })\n// after\nnew RoundRobinPool(url, { factory: (origin, opts) => new Client(origin, opts) })","handlingStrategy":"type-guard","validationCode":"if (cfg.factory != null && typeof cfg.factory !== 'function') {\n  throw new TypeError('factory must be a function/class reference, not an instance')\n}\nnew RoundRobinPool(url, { factory: cfg.factory })","typeGuard":"function isFactory(v) { return v == null || typeof v === 'function' }","tryCatchPattern":null,"preventionTips":["Pass a class/function reference, never an instance.","Keep factory in code, not deserialized JSON.","Use connect for custom sockets instead of factory."],"tags":["undici","round-robin-pool","factory","invalid-arg"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}