jackwener/OpenCLI · warning · CommandExecutionError

hf paper returned HTTP 429 (rate limited)

Error message

hf paper returned HTTP 429 (rate limited)

What it means

CommandExecutionError('hf paper returned HTTP 429 (rate limited)') thrown when Hugging Face responds 429 to the unauthenticated /api/papers request. The library calls out that HF throttles unauthenticated traffic and the fix is simply to wait and retry — no retry/backoff is performed automatically.

Source

Thrown at clis/hf/paper.js:45

            throw new ArgumentError(
                `hf paper id "${args.id}" is not a valid arXiv id`,
                'Expected the modern arXiv form `YYMM.NNNNN` (optionally with a version suffix like `v3`).',
            );
        }
        const endpoint = process.env.HF_ENDPOINT?.replace(/\/+$/, '') || 'https://huggingface.co';
        const url = `${endpoint}/api/papers/${encodeURIComponent(raw)}`;
        let resp;
        try {
            resp = await fetch(url, { headers: { accept: 'application/json' } });
        }
        catch (err) {
            throw new CommandExecutionError(`hf paper request failed: ${err?.message ?? err}`);
        }
        if (resp.status === 404) {
            throw new EmptyResultError('hf paper', `Hugging Face has no paper page for "${raw}".`);
        }
        if (resp.status === 429) {
            throw new CommandExecutionError(
                'hf paper returned HTTP 429 (rate limited)',
                'Hugging Face throttles unauthenticated traffic; wait a few seconds and retry.',
            );
        }
        if (!resp.ok) {
            throw new CommandExecutionError(`hf paper returned HTTP ${resp.status}`);
        }
        let body;
        try {
            body = await resp.json();
        }
        catch (err) {
            throw new CommandExecutionError(`hf paper returned malformed JSON: ${err?.message ?? err}`);
        }
        if (!body || typeof body !== 'object' || !body.id) {
            throw new EmptyResultError('hf paper', `Hugging Face returned no paper data for "${raw}".`);
        }
        const authors = Array.isArray(body.authors)

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Wait a few seconds (or longer, per any Retry-After header) and rerun the command.
  2. Add backoff/jitter between calls if scripting many lookups (e.g. sleep 2 between invocations).
  3. Set HF_ENDPOINT to an authenticated or less-throttled mirror if available and permitted.
  4. Reduce parallelism — run lookups sequentially rather than in parallel loops.
  5. Check whether a shared egress IP (VPN, corporate proxy, CI runner) is the source and switch networks if possible.

Example fix

// before (shell loop, no delay)
for id in $(cat ids.txt); do opencli hf paper $id; done
// after
for id in $(cat ids.txt); do opencli hf paper $id; sleep 2; done
Defensive patterns

Strategy: retry

Validate before calling

// throttle client-side before calling: at most 1 request per 2s
const MIN_INTERVAL_MS = 2000;
let last = 0;
async function throttledRun(id) {
  const wait = Math.max(0, last + MIN_INTERVAL_MS - Date.now());
  await new Promise(r => setTimeout(r, wait));
  last = Date.now();
  return run(['opencli', 'hf paper', id]);
}

Type guard

function isRateLimited(e) {
  return e instanceof Error && /HTTP 429/.test(e.message);
}

Try / catch

async function withRetry(fn, attempts = 5) {
  for (let i = 0; i < attempts; i++) {
    try { return await fn(); }
    catch (e) {
      if (/HTTP 429/.test(e.message) && i < attempts - 1) {
        await new Promise(r => setTimeout(r, 2 ** i * 1000 + Math.random() * 500));
        continue;
      }
      throw e;
    }
  }
}

Prevention

When it happens

Trigger: GET /api/papers/<id> returns HTTP 429 because the client IP exceeded HF's anonymous rate limit — typically after issuing many hf/hf-paper queries in quick succession or running the command in a loop/script.

Common situations: Batch scripts iterating over many paper ids; shared CI runner IPs already throttled by HF; running the command repeatedly while debugging; VPN/proxy egress IP shared by many users.

Understand the failure class

Related errors


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