nodejs/node · error · InvalidArgumentError
UND_ERR_INVALID_ARG
UND_ERR_INVALID_ARG
Error message
factory must be a function.
What it means
Thrown by the BalancedPool constructor. The factory option chooses how each upstream Pool is built (default returns new Pool(origin, opts)). BalancedPool calls factory(origin, opts) when addUpstream runs, so it must be a function; a class reference or object cannot be invoked.
Source
Thrown at deps/undici/src/lib/dispatcher/balanced-pool.js:54
function getGreatestCommonDivisor (a, b) {
if (a === 0) return b
while (b !== 0) {
const t = b
b = a % b
a = t
}
return a
}
function defaultFactory (origin, opts) {
return new Pool(origin, opts)
}
class BalancedPool extends PoolBase {
constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) {
if (typeof factory !== 'function') {
throw new InvalidArgumentError('factory must be a function.')
}
super()
this[kOptions] = { ...util.deepClone(opts) }
this[kIndex] = -1
this[kCurrentWeight] = 0
this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100
this[kErrorPenalty] = this[kOptions].errorPenalty || 15
if (!Array.isArray(upstreams)) {
upstreams = [upstreams]
}
this[kFactory] = factory
for (const upstream of upstreams) {View on GitHub (pinned to 1b2de5e052)
Solutions
- Provide factory as a function returning a Dispatcher: new BalancedPool(urls, { factory: (origin, opts) => new Pool(origin, opts) }).
- Omit factory to use the default (which already builds a Pool per upstream).
- Verify the imported Pool/Client is defined before referencing it inside the factory.
Example fix
// before
const pool = new BalancedPool(['a.com', 'b.com'], { factory: Pool })
// after
const pool = new BalancedPool(['a.com', 'b.com'], { factory: (origin, opts) => new Pool(origin, opts) }) Defensive patterns
Strategy: type-guard
Validate before calling
function buildBalancedPool(upstreams, options = {}) {
if (options.factory !== undefined && typeof options.factory !== 'function') {
throw new TypeError('BalancedPool factory must be a function')
}
return new BalancedPool(upstreams, options)
} Type guard
const isFactory = (f) => typeof f === 'function'
Prevention
- Pass factory as a function returning a Pool/Client, not the class itself.
- Omit factory to use the default Pool-creating implementation.
When it happens
Trigger: new BalancedPool(upstreams, { factory: Pool }), new BalancedPool([], { factory: {} }), or a factory import that resolved to undefined.
Common situations: Passing the Pool class directly instead of a constructor wrapper; sharing one factory function across Agent and BalancedPool with the wrong shape; a config merge that overwrote factory.
Related errors
- UND_ERR_INVALID_ARG
- SqliteCacheStore options must be an object
- UND_ERR_BPL_MISSING_UPSTREAM
- UND_ERR_INVALID_ARG
- UND_ERR_INVALID_ARG
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/03836e3fdccaad78.
Report an issue: GitHub.