nodejs/node · error · InvalidArgumentError
factory must be a function.
Error message
factory must be a function.
What it means
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'.
Source
Thrown at deps/undici/src/lib/dispatcher/round-robin-pool.js:49
connections,
factory = defaultFactory,
connect,
connectTimeout,
tls,
maxCachedSessions,
socketPath,
autoSelectFamily,
autoSelectFamilyAttemptTimeout,
allowH2,
clientTtl,
...options
} = {}) {
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
throw new InvalidArgumentError('invalid connections')
}
if (typeof factory !== 'function') {
throw new InvalidArgumentError('factory must be a function.')
}
if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {
throw new InvalidArgumentError('connect must be a function or an object')
}
if (typeof connect !== 'function') {
connect = buildConnector({
...tls,
maxCachedSessions,
allowH2,
socketPath,
timeout: connectTimeout,
...(typeof autoSelectFamily === 'boolean' ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),
...connect
})
}
View on GitHub (pinned to 1b2de5e052)
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.
Example fix
// before
new RoundRobinPool(url, { factory: new Client(url) })
// after
new RoundRobinPool(url, { factory: (origin, opts) => new Client(origin, opts) }) Defensive patterns
Strategy: type-guard
Validate before calling
if (cfg.factory != null && typeof cfg.factory !== 'function') {
throw new TypeError('factory must be a function/class reference, not an instance')
}
new RoundRobinPool(url, { factory: cfg.factory }) Type guard
function isFactory(v) { return v == null || typeof v === 'function' } Prevention
- Pass a class/function reference, never an instance.
- Keep factory in code, not deserialized JSON.
- Use connect for custom sockets instead of factory.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Proxy opts.clientFactory must be a function.
- invalid connections
- connect must be a function or an object
- UND_ERR_INVALID_ARG
- UND_ERR_INVALID_ARG
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/ba47a7899fbbc26a.
Report an issue: GitHub.