{"record":{"id":"06a556ece6353c80","repo":"jackwener/OpenCLI","slug":"hf-spaces-returned-http-429-rate-limited","errorCode":null,"errorMessage":"hf spaces returned HTTP 429 (rate limited)","messagePattern":"hf spaces returned HTTP 429 \\(rate limited\\)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":429,"severity":"warning","filePath":"clis/hf/spaces.js","lineNumber":65,"sourceCode":"        const url = new URL('https://huggingface.co/api/spaces');\n        url.searchParams.set('sort', sort);\n        url.searchParams.set('direction', '-1');\n        url.searchParams.set('limit', String(limit));\n        url.searchParams.set('full', 'true');\n        if (args.search) url.searchParams.set('search', String(args.search));\n        if (sdk) url.searchParams.set('sdk', sdk);\n\n        let resp;\n        try {\n            resp = await fetch(url, {\n                headers: { Accept: 'application/json', 'User-Agent': 'opencli/1.0 (+https://github.com/jackwener/opencli)' },\n            });\n        }\n        catch (err) {\n            throw new CommandExecutionError(`hf spaces request failed: ${err?.message ?? err}`);\n        }\n        if (resp.status === 429) {\n            throw new CommandExecutionError(\n                'hf spaces returned HTTP 429 (rate limited)',\n                'Hugging Face throttles unauthenticated traffic; wait a few seconds and retry.',\n            );\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`hf spaces failed: HTTP ${resp.status}`);\n        }\n        let data;\n        try {\n            data = await resp.json();\n        }\n        catch (err) {\n            throw new CommandExecutionError(`hf spaces returned malformed JSON: ${err?.message ?? err}`);\n        }\n        const list = Array.isArray(data) ? data : [];\n        if (!list.length) {\n            throw new EmptyResultError('hf spaces', 'No matching spaces on huggingface.co.');\n        }","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hf/spaces.js#L47-L83","documentation":"The Hugging Face Spaces API responded with HTTP 429 Too Many Requests, meaning the server is rate-limiting this client. The library detects status 429 explicitly and appends guidance: Hugging Face throttles unauthenticated traffic, so wait and retry.","triggerScenarios":"Calling `hf spaces` (GET /api/spaces) too frequently without authentication, so HF's per-IP anonymous rate limit is exceeded and the server returns 429.","commonSituations":"Scripts or CI pipelines polling the spaces endpoint in a loop without delays; shared CI runner IPs that are already throttled by HF; bursty retries after other failures.","solutions":["Wait a few seconds and retry with exponential backoff","Authenticate requests with an HF token (Authorization: Bearer hf_...) to get a higher rate limit","Add spacing/jitter between repeated calls or cache results","Reduce polling frequency in scripts/CI"],"exampleFix":"// before: tight loop hammering the API\nfor (const q of queries) await listSpaces(q);\n// after\nfor (const q of queries) {\n  await listSpaces(q);\n  await new Promise((r) => setTimeout(r, 2000));\n}","handlingStrategy":"retry","validationCode":"// throttle your own calls: simple client-side rate limiter\nlet last = 0;\nasync function throttled(fn, minGapMs = 2000) {\n  const wait = last + minGapMs - Date.now();\n  if (wait > 0) await new Promise(r => setTimeout(r, wait));\n  last = Date.now();\n  return fn();\n}","typeGuard":null,"tryCatchPattern":"async function withBackoff(fn, tries = 4) {\n  for (let i = 0; i < tries; i++) {\n    try { return await fn(); }\n    catch (e) {\n      if (!String(e.message).includes('429') || i === tries - 1) throw e;\n      await new Promise(r => setTimeout(r, 2 ** i * 1000));\n    }\n  }\n}","preventionTips":["Authenticate with an HF token to raise rate limits","Cache spaces listings instead of re-fetching","Add delays between repeated calls in scripts/CI","Use exponential backoff on any 429"],"tags":["rate-limit","http-429","huggingface","retry"],"backgroundTag":"http-429-rate-limited","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}