jackwener/OpenCLI · error · CommandExecutionError
stack exchange returned HTTP 429 (rate limited)
Error message
stack exchange returned HTTP 429 (rate limited)
What it means
CommandExecutionError thrown by seFetch when the Stack Exchange API responds with HTTP 429, meaning the client has exceeded the anonymous quota (300 requests/day per IP for unauthenticated calls, per the file's header comment). The suggestion field advises waiting or lowering --limit.
Source
Thrown at clis/stackoverflow/utils.js:63
url.searchParams.set(k, String(v));
}
}
if (!url.searchParams.has('site')) url.searchParams.set('site', SE_SITE);
let resp;
try {
resp = await fetch(url, {
headers: {
'Accept': 'application/json',
'Accept-Encoding': 'gzip',
'User-Agent': UA,
},
});
} catch (error) {
throw new CommandExecutionError(`stack exchange request failed: ${error?.message || error}`);
}
if (resp.status === 429) {
throw new CommandExecutionError('stack exchange returned HTTP 429 (rate limited)', 'Wait a few seconds and retry, or lower --limit.');
}
if (!resp.ok) {
let body = '';
try { body = (await resp.json())?.error_message || ''; } catch { /* ignore */ }
throw new CommandExecutionError(`stack exchange HTTP ${resp.status}: ${body || resp.statusText}`);
}
let data;
try {
data = await resp.json();
} catch (error) {
throw new CommandExecutionError(`stack exchange returned malformed JSON: ${error?.message || error}`);
}
if (data?.error_id) {
throw new CommandExecutionError(
`stack exchange API error: ${data.error_message || data.error_name}`,
'Inspect the URL in a browser for the canonical error context.',
);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Wait until the daily quota resets, then retry.
- Reduce request volume: lower --limit, batch ids via /questions/{ids};-separated paths, cache responses.
- Register a Stack Apps app key to raise the quota to 10,000 requests/day and pass key as a search param.
- Authenticate with OAuth for a 30,000/day quota on behalf of a user.
- Cache results locally so repeat invocations don't re-hit the API.
Example fix
// before: immediate retry loop
for (const id of ids) await read(id);
// after: batch + throttle
const chunks = chunk(ids, 100);
for (const c of chunks) {
await seFetch(`/questions/${c.join(';')}?site=stackoverflow&filter=withbody`);
await sleep(500);
} Defensive patterns
Strategy: retry
Validate before calling
function withKey(url) { return url + (process.env.SE_APP_KEY ? `${url.includes('?') ? '&' : '?'}key=${process.env.SE_APP_KEY}` : ''); } // raises quota from 300 to 10,000/day Try / catch
async function fetchRespecting429(path) {
try {
return await seFetch(path);
} catch (e) {
if (String(e.message).includes('HTTP 429')) {
const retryAfter = 10 + Math.random() * 5;
await new Promise(r => setTimeout(r, retryAfter * 1000));
return seFetch(path);
}
throw e;
}
} Prevention
- Register a Stack Apps app key and send it as `key` to get 10,000 requests/day.
- Throttle batch jobs (e.g. sleep between calls) and cache responses to disk.
- Batch ids via /questions/{id};{id} paths instead of one call per id.
- Remember the quota is per-IP — coordinate across teammates/CI sharing an egress IP.
- Lower --limit/pagesize; large pagesizes don't consume extra quota but big loops do.
When it happens
Trigger: More than ~300 api.stackexchange.com calls per day from one IP; a burst of automated queries/agents sharing an IP (CI runners, office NAT); repeatedly re-running searches with large pagesizes.
Common situations: CI pipelines hammering the API on every build; multiple team members behind one corporate egress IP; scripts looping over many question ids in a short window; shared cloud/VPN egress IPs that are already exhausted.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- coingecko returned HTTP 429 (rate limited)
- coingecko returned HTTP 429 (rate limited)
- ${label} returned HTTP 429 (rate limited)
- ${label} returned HTTP 429 (rate limited)
- coingecko returned HTTP 429 (rate limited)
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b0bfe6956f5f4096.
Report an issue: GitHub.