badges/shields · error · ImproperlyConfigured
Unable to select next Libraries.io token from pool
Error message
Unable to select next Libraries.io token from pool
What it means
Libraries.io requests in Shields use a pool of API tokens that are rotated to spread rate limits. When withPooling is enabled, the service pulls the next token from StandardTokens.next(); if that call throws (e.g. no tokens are available or the pool is misconfigured), the error is wrapped in an ImproperlyConfigured with this message. It is a service configuration problem, not a network or user error.
Source
Thrown at services/librariesio/librariesio-api-provider.js:79
updateToken({ token, res }) {
const { totalUsesRemaining, nextReset } = this.getRateLimitFromHeaders({
headers: res.headers,
token,
})
token.update(totalUsesRemaining, nextReset)
}
async fetch(requestFetcher, url, options = {}) {
const { baseUrl } = this
let token
let tokenString
if (this.withPooling) {
try {
token = this.standardTokens.next()
} catch (e) {
log.error(e)
throw new ImproperlyConfigured({
prettyMessage: 'Unable to select next Libraries.io token from pool',
})
}
tokenString = token.id
} else {
tokenString = this.globalToken
}
const mergedOptions = {
...options,
...{
headers: {
'User-Agent': userAgent,
...options.headers,
},
searchParams: {
api_key: tokenString,
...options.searchParams,View on GitHub (pinned to 766fd8bc89)
Solutions
- Add at least one valid Libraries.io API token to the configured token pool (env/config).
- If you only have one token, disable pooling and set globalToken instead.
- Verify the token pool module (StandardTokens) is constructed with the configured credentials and that token entries have an id field.
- Regenerate the Libraries.io API key if existing tokens were revoked.
Example fix
// before withPooling: true // but no tokens in pool // after withPooling: false, globalToken: process.env.LIBRARIES_IO_TOKEN
Defensive patterns
Strategy: try-catch
Validate before calling
if (!tokens || tokens.length === 0) throw new Error('Libraries.io token pool is empty; configure LIBRARIES_IO_TOKEN') Type guard
null
Try / catch
try {
const badge = await librariesioProvider.fetch(params)
} catch (e) {
if (e instanceof ImproperlyConfigured && e.prettyMessage.includes('token')) {
// fix config: supply/rotate Libraries.io tokens, then retry
}
throw e
} Prevention
- Always provision at least one valid Libraries.io token in the environment before enabling the service.
- Monitor Libraries.io rate limits and rotate tokens before expiry/revocation.
- Only enable withPooling when the pool is guaranteed non-empty; otherwise use globalToken.
When it happens
Trigger: Instantiating the Libraries.io provider with withPooling=true but an empty or invalid token pool, so standardTokens.next() throws when fetch() selects a token.
Common situations: Deploying without configuring the Libraries.io token pool in the environment, all configured tokens having been removed or invalidated, or accidentally enabling pooling when only a single global token is set.
Related errors
- Unable to select next GitHub token from pool
- job not found
- repo not found: ${repoName}
- bucket "${bucket}" not found
- ${app} not found in bucket "${bucket}"
AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30).
Data as JSON: /api/errors/c91dd7aa72c6fb17.
Report an issue: GitHub.