{"record":{"id":"358cea3082ce3b7c","repo":"nodejs/node","slug":"und-err-bpl-missing-upstream","errorCode":"UND_ERR_BPL_MISSING_UPSTREAM","errorMessage":"No upstream has been added to the BalancedPool","messagePattern":"No upstream has been added to the BalancedPool","errorType":"exception","errorClass":"BalancedPoolMissingUpstreamError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/dispatcher/balanced-pool.js","lineNumber":164,"sourceCode":"    return this[kClients].find((pool) => (\n      pool[kUrl].origin === upstreamOrigin &&\n      pool.closed !== true &&\n      pool.destroyed !== true\n    ))\n  }\n\n  get upstreams () {\n    return this[kClients]\n      .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true)\n      .map((p) => p[kUrl].origin)\n  }\n\n  [kGetDispatcher] () {\n    // We validate that pools is greater than 0,\n    // otherwise we would have to wait until an upstream\n    // is added, which might never happen.\n    if (this[kClients].length === 0) {\n      throw new BalancedPoolMissingUpstreamError()\n    }\n\n    let counter = 0\n\n    let maxWeightIndex = -1\n\n    while (counter++ < this[kClients].length) {\n      this[kIndex] = (this[kIndex] + 1) % this[kClients].length\n      const pool = this[kClients][this[kIndex]]\n\n      // decrease the current weight every `this[kClients].length`.\n      if (this[kIndex] === 0) {\n        // Set the current weight to the next lower weight.\n        this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor]\n\n        if (this[kCurrentWeight] <= 0) {\n          this[kCurrentWeight] = this[kMaxWeightPerServer]\n        }","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/dispatcher/balanced-pool.js#L146-L182","documentation":"Thrown by BalancedPool's [kGetDispatcher] as BalancedPoolMissingUpstreamError (code UND_ERR_BPL_MISSING_UPSTREAM). The pool intentionally refuses to dispatch when this[kClients].length === 0 rather than queue a request that could wait forever for an upstream that may never arrive. So any dispatch before addUpstream has been called fails fast.","triggerScenarios":"new BalancedPool() with no upstreams, then pool.request(...) or pool.dispatch(...); or all upstreams were removed/closed leaving kClients empty.","commonSituations":"Constructing a BalancedPool with an empty array and forgetting to call addUpstream; a race where the pool is used before the bootstrap that populates it runs; dynamic reconfiguration that removes every upstream.","solutions":["Add at least one upstream before dispatching: pool.addUpstream('https://upstream1.example.com').","Pass upstreams in the constructor: new BalancedPool(['https://a.com', 'https://b.com']).","Re-check pool.upstreams.length before dispatching when the pool is reconfigured dynamically."],"exampleFix":"// before\nconst pool = new BalancedPool()\nawait pool.request({ method: 'GET', path: '/' }) // throws\n// after\nconst pool = new BalancedPool(['https://a.com', 'https://b.com'])\nawait pool.request({ method: 'GET', path: '/' })","handlingStrategy":"validation","validationCode":"function safeRequest(pool, opts) {\n  if (pool.upstreams.length === 0) throw new Error('BalancedPool has no upstreams')\n  return pool.request(opts)\n}","typeGuard":"const hasUpstreams = (pool) => Array.isArray(pool.upstreams) && pool.upstreams.length > 0","tryCatchPattern":"try {\n  await pool.request(opts)\n} catch (e) {\n  if (e.code === 'UND_ERR_BPL_MISSING_UPSTREAM') { pool.addUpstream(DEFAULT_UPSTREAM); /* retry */ }\n  else throw e\n}","preventionTips":["Always construct BalancedPool with at least one upstream or call addUpstream before dispatch.","Check pool.upstreams.length during dynamic reconfiguration."],"tags":["undici","balanced-pool","upstream","dispatch","validation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}