jackwener/OpenCLI · error · CommandExecutionError

arXiv API HTTP ${resp.status}

Error message

arXiv API HTTP ${resp.status}

What it means

CommandExecutionError thrown by arxivFetch when the arXiv export API responds with a non-OK HTTP status. The library treats any failed fetch of https://export.arxiv.org/api/query as a command execution failure and surfaces the HTTP status code in the message. It indicates the request itself reached the server but was rejected (4xx/5xx), e.g. a malformed query string or arXiv-side outage.

Source

Thrown at clis/arxiv/utils.js:13

/**
 * arXiv adapter utilities.
 *
 * arXiv exposes a public Atom/XML API — no key required.
 * https://info.arxiv.org/help/api/index.html
 */
import { ArgumentError, CommandExecutionError } from '@jackwener/opencli/errors';
export const ARXIV_BASE = 'https://export.arxiv.org/api/query';
const ARXIV_CATEGORY_PATTERN = /^[a-z]+(?:-[a-z]+)*(?:\.[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)?$/;
export async function arxivFetch(params) {
    const resp = await fetch(`${ARXIV_BASE}?${params}`);
    if (!resp.ok) {
        throw new CommandExecutionError(`arXiv API HTTP ${resp.status}`, 'Check your search term or paper ID');
    }
    return resp.text();
}
export function normalizeArxivLimit(value, defaultValue, maxValue, label = 'limit') {
    const raw = value ?? defaultValue;
    const limit = Number(raw);
    if (!Number.isInteger(limit) || limit <= 0) {
        throw new ArgumentError(`arxiv ${label} must be a positive integer`);
    }
    if (limit > maxValue) {
        throw new ArgumentError(`arxiv ${label} must be <= ${maxValue}`);
    }
    return limit;
}
export function normalizeArxivCategory(value) {
    const category = String(value || '').trim();
    if (!ARXIV_CATEGORY_PATTERN.test(category)) {
        throw new ArgumentError(`Invalid arXiv category "${value}". Examples: cs.CL, cs.LG, math.PR, q-bio.NC, physics.comp-ph`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the message's HTTP status: if 503/429, wait (arXiv asks for ~3s between requests) and retry with backoff.
  2. Verify the search term or paper ID is well-formed (e.g. paper IDs like 2401.12345v1).
  3. Check https://status.arxiv.org or hit the ARXIV_BASE URL in a browser to confirm the API is up.
  4. If behind a corporate proxy, confirm the proxy allows export.arxiv.org.

Example fix

// before
const text = await arxivFetch('search_query=bad term');
// after: retry with delay on 5xx/429
try {
  const text = await arxivFetch('search_query=all:electron&max_results=5');
} catch (e) {
  await new Promise(r => setTimeout(r, 3000));
  const text = await arxivFetch('search_query=all:electron&max_results=5');
}
Defensive patterns

Strategy: retry

Try / catch

try {
  const xml = await arxivFetch(params);
} catch (e) {
  if (e instanceof CommandExecutionError && /HTTP (429|503)/.test(e.message)) {
    await sleep(3000); // honor arXiv rate limits, then retry
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Any call path that fetches from the arXiv API (search by term, paper ID, category listing) where the server returns a non-2xx response: malformed params, rate limiting (HTTP 429/503), or arXiv export API downtime.

Common situations: arXiv throttles clients that poll too fast (503 with Retry-After); temporary outages of export.arxiv.org; constructing an invalid query string upstream so the API rejects it; network proxies returning 4xx/5xx.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/7bcda9b51dec044d. Report an issue: GitHub.