jackwener/OpenCLI · error · CommandExecutionError
${label} returned HTTP 429 (rate limited)
Error message
${label} returned HTTP 429 (rate limited) What it means
mavenFetch() detects HTTP 429 from search.maven.org and throws a CommandExecutionError indicating the request was rate limited. Maven Central's Solr endpoint throttles bursts of requests.
Source
Thrown at clis/maven/utils.js:86
return { groupId, artifactId, version: version ?? null };
}
export async function mavenFetch(url, label) {
let resp;
try {
resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });
}
catch (err) {
throw new CommandExecutionError(
`${label} request failed: ${err?.message ?? err}`,
'Check that search.maven.org is reachable from this network.',
);
}
if (resp.status === 404) {
throw new EmptyResultError(label, `Maven Central returned 404 for ${url}.`);
}
if (resp.status === 429) {
throw new CommandExecutionError(
`${label} returned HTTP 429 (rate limited)`,
'Maven Central throttles bursts; wait a few seconds and retry.',
);
}
if (!resp.ok) {
throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);
}
let body;
try {
body = await resp.json();
}
catch (err) {
throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);
}
return body;
}
/** Convert epoch-ms (Maven Solr `timestamp`) to ISO-8601 UTC. Returns null for falsy/invalid. */View on GitHub (pinned to 49907e53dc)
Solutions
- Wait a few seconds and retry — the throttle is temporary.
- Add exponential backoff with jitter around mavenFetch calls.
- Rate-limit your own requests (e.g. a few hundred ms between lookups).
- Batch queries where possible (Solr rows/q parameter) instead of one request per coordinate.
Example fix
// before
for (const c of coords) results.push(await lookup(c));
// after
for (const c of coords) {
results.push(await withBackoff(() => lookup(c)));
await sleep(250); // stay under Maven Central rate limits
} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
async function withBackoff(fn, attempts = 4) {
for (let i = 0; ; i++) {
try { return await fn(); }
catch (err) {
if (!/429/.test(err.message) || i >= attempts) throw err;
await sleep(2 ** i * 500 + Math.random() * 250);
}
}
}
const data = await withBackoff(() => mavenFetch(url, 'search')); Prevention
- Throttle your own request rate (e.g. 200-500ms between calls).
- Use exponential backoff with jitter on any 429.
- Batch queries into fewer Solr requests instead of per-coordinate calls.
- Avoid tight retry loops — they prolong the throttle.
When it happens
Trigger: Making many maven lookups in rapid succession (batch scripts, CI loops, fan-out queries) until search.maven.org responds 429.
Common situations: Iterating over hundreds of dependencies with no delay; shared CI runners where many jobs hit the same unauthenticated endpoint; retry loops without backoff amplifying the throttling.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- coingecko derivatives returned HTTP 429 (rate limited)
- coingecko returned HTTP 429 (rate limited)
- ${label} returned HTTP 429 (rate limited)
- hf spaces returned HTTP 429 (rate limited)
- ${label} returned HTTP 429 (rate limited)
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c96b394091f8be96.
Report an issue: GitHub.