jackwener/OpenCLI · error · CommandExecutionError

hf models failed: HTTP ${resp.status}

Error message

hf models failed: HTTP ${resp.status}

What it means

CommandExecutionError thrown at clis/hf/models.js:61 when the HTTP response from https://huggingface.co/api/models arrives but resp.ok is false — i.e. any non-2xx status (404, 429, 5xx, etc.). The library reports the raw status code because the models endpoint does not receive per-status handling (unlike paper.js which special-cases 404 and 429).

Source

Thrown at clis/hf/models.js:61

        url.searchParams.set('direction', '-1');
        url.searchParams.set('limit', String(limit));
        url.searchParams.set('full', 'true');
        if (args.search) url.searchParams.set('search', String(args.search));
        if (args.pipeline) url.searchParams.set('pipeline_tag', String(args.pipeline));

        let resp;
        try {
            resp = await fetch(url, {
                headers: {
                    'Accept': 'application/json',
                    'User-Agent': 'opencli/1.0 (+https://github.com/jackwener/opencli)',
                },
            });
        } catch (error) {
            throw new CommandExecutionError(`hf models request failed: ${error?.message || error}`);
        }
        if (!resp.ok) {
            throw new CommandExecutionError(`hf models failed: HTTP ${resp.status}`);
        }
        let data;
        try {
            data = await resp.json();
        } catch (error) {
            throw new CommandExecutionError(`hf models returned malformed JSON: ${error?.message || error}`);
        }
        const list = Array.isArray(data) ? data : [];
        if (list.length === 0) {
            throw new EmptyResultError('hf models', 'No matching models on huggingface.co.');
        }
        return list.slice(0, limit).map((m, i) => {
            const id = m.id || m.modelId || '';
            const slashIdx = id.indexOf('/');
            const author = slashIdx > 0 ? id.slice(0, slashIdx) : '';
            const tags = Array.isArray(m.tags) ? m.tags.filter(t => !t.startsWith('license:')).slice(0, 10).join(', ') : '';
            return {
                rank: i + 1,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the status in the message: 429 means back off and retry after a delay; 5xx means retry later or check HF status; 403/401 from a proxy means fix proxy/auth.
  2. Add delay/exponential backoff around the command when 429 occurs (HF throttles unauthenticated traffic).
  3. Run curl -sS -o /dev/null -w '%{http_code}' 'https://huggingface.co/api/models?limit=1' to confirm whether the status reproduces outside the CLI.
  4. If a proxy/CDN intercepts, bypass or reconfigure it so requests reach huggingface.co directly.

Example fix

// before
for (const q of queries) { await run('hf models --search ' + q); } // hammers API -> 429
// after
for (const q of queries) {
  await run('hf models --search ' + q);
  await new Promise(r => setTimeout(r, 2000)); // avoid rate limiting
}
Defensive patterns

Strategy: retry

Validate before calling

// Detect likely rate limiting before hammering the API
const r = await fetch('https://huggingface.co/api/models?limit=1');
if (r.status === 429) {
  const wait = Number(r.headers.get('retry-after') ?? 5);
  console.error(`HF rate limited; wait ${wait}s before running hf models`);
}

Try / catch

try {
  await run('hf models --search ' + q);
} catch (e) {
  const m = String(e.message).match(/HTTP (\d+)/);
  if (m && m[1] === '429') {
    await new Promise(r => setTimeout(r, 5000)); // back off on rate limit
    await run('hf models --search ' + q);
  } else if (m && m[1].startsWith('5')) {
    await new Promise(r => setTimeout(r, 30000)); // server-side issue
  } else throw e;
}

Prevention

When it happens

Trigger: Hugging Face API returning an error status for GET /api/models: HTTP 429 when unauthenticated traffic is rate-limited, 5xx during HF incidents, 404/blocked responses from intermediaries, or a proxy returning an error page.

Common situations: Scripting the CLI in a tight loop and triggering HF rate limiting (429); huggingface.co partial outage returning 502/503; a corporate proxy returning 403 for the API path; stale DNS pinning to a wrong host returning 404.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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