jackwener/OpenCLI · error · CommandExecutionError
${label} HTTP ${response.status}
Error message
${label} HTTP ${response.status} What it means
After a successful fetch, eutilsFetch checks response.ok; a non-2xx status (429 rate limit, 5xx NCBI errors, 403) throws CommandExecutionError '<label> HTTP <status>' with a hint about NCBI availability, parameters, and the optional NCBI_API_KEY. Called by the xml, esearch, and result paths.
Source
Thrown at clis/pubmed/utils.js:106
if (waitMs > 0) {
await new Promise(resolve => setTimeout(resolve, waitMs));
}
lastRequestAt = Date.now();
}
export async function eutilsFetch(tool, params = {}, { retmode = 'json', label = 'PubMed E-utilities' } = {}) {
const url = buildEutilsUrl(tool, { ...params, retmode });
await waitForRateLimit();
let response;
try {
response = await fetch(url);
}
catch (error) {
const detail = error instanceof Error ? error.message : String(error);
throw new CommandExecutionError(`${label} request failed`, detail);
}
if (!response.ok) {
throw new CommandExecutionError(`${label} HTTP ${response.status}`, 'Check NCBI availability, request parameters, and optional NCBI_API_KEY.');
}
if (retmode === 'xml') {
return response.text();
}
try {
const json = await response.json();
assertNoEutilsError(json, label);
return json;
}
catch (error) {
if (error instanceof CommandExecutionError) {
throw error;
}
const detail = error instanceof Error ? error.message : String(error);
throw new CommandExecutionError(`${label} returned invalid JSON`, detail);
}
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Request a free NCBI_API_KEY and export it (raises the limit from 3 to 10 req/s)
- Add delays between sequential calls (e.g. sleep 400ms) to respect rate limits
- Retry with backoff on 429/5xx; check NCBI status on persistent 5xx
- Review request parameters if the status is 4xx
Example fix
// before
for (const q of queries) await pubmedSearch(q); // bursts >3 req/s
// after
export NCBI_API_KEY=your_key_here
for (const q of queries) {
await pubmedSearch(q);
await new Promise(r => setTimeout(r, 150));
} Defensive patterns
Strategy: retry
Validate before calling
// space requests to stay under 3 req/s without an API key await new Promise(r => setTimeout(r, 400)); // between calls // and export NCBI_API_KEY=... to allow 10 req/s
Try / catch
async function withStatusRetry(fn, attempts = 3) {
for (let i = 1; i <= attempts; i++) {
try { return await fn(); }
catch (err) {
const m = /HTTP (\d+)/.exec(err.message ?? '');
const status = m && Number(m[1]);
if (status && (status === 429 || status >= 500) && i < attempts) {
await new Promise(r => setTimeout(r, 2 ** i * 1000));
continue;
}
throw err;
}
}
} Prevention
- Register for an NCBI_API_KEY and export it in your environment
- Throttle sequential calls to stay under the per-second rate limit
- Back off exponentially on 429/5xx responses
- Keep tool/email parameters valid and check NCBI status on persistent 5xx
When it happens
Trigger: Any pubmed command when NCBI returns 429 from exceeding 3 requests/second without an API key, 5xx during NCBI incidents, or 4xx from malformed eutils parameters.
Common situations: Burst-running many searches in a loop without an NCBI_API_KEY, NCBI maintenance windows, invalid tool/email parameters, blocked user agents.
Related errors
- archive snapshots failed: HTTP ${resp.status}
- DuckDuckGo suggest returned HTTP ${resp.status}
- Instagram private publish ${stage} failed: ${response.status
- Failed to fetch followers: HTTP ' + r2.status
- Failed to fetch following: HTTP ' + r2.status
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0548b383e5daaf60.
Report an issue: GitHub.