jackwener/OpenCLI · error · CommandExecutionError
hf spaces returned malformed JSON: ${err?.message ?? err}
Error message
hf spaces returned malformed JSON: ${err?.message ?? err} What it means
The response body from the Hugging Face Spaces API could not be parsed as JSON. The library assumes the endpoint returns a JSON array of spaces, so resp.json() throwing is wrapped in a CommandExecutionError with the parse failure message.
Source
Thrown at clis/hf/spaces.js:78
}
catch (err) {
throw new CommandExecutionError(`hf spaces request failed: ${err?.message ?? err}`);
}
if (resp.status === 429) {
throw new CommandExecutionError(
'hf spaces returned HTTP 429 (rate limited)',
'Hugging Face throttles unauthenticated traffic; wait a few seconds and retry.',
);
}
if (!resp.ok) {
throw new CommandExecutionError(`hf spaces failed: HTTP ${resp.status}`);
}
let data;
try {
data = await resp.json();
}
catch (err) {
throw new CommandExecutionError(`hf spaces returned malformed JSON: ${err?.message ?? err}`);
}
const list = Array.isArray(data) ? data : [];
if (!list.length) {
throw new EmptyResultError('hf spaces', 'No matching spaces on huggingface.co.');
}
return list.slice(0, limit).map((s, i) => {
const id = String(s.id ?? s._id ?? '');
const slash = id.indexOf('/');
const author = String(s.author ?? (slash > 0 ? id.slice(0, slash) : ''));
const tags = Array.isArray(s.tags) ? s.tags.filter((t) => !String(t).startsWith('license:')).slice(0, 10).join(', ') : '';
return {
rank: i + 1,
id,
author,
sdk: String(s.sdk ?? ''),
likes: s.likes != null ? Number(s.likes) : null,
tags,
lastModified: String(s.lastModified ?? '').slice(0, 10),View on GitHub (pinned to 49907e53dc)
Solutions
- Log resp.headers.get('content-type') and the raw body to see what was actually returned
- Verify the request reaches the real HF API (no proxy interference) with curl
- Retry; if consistent, check HF status page for API incidents
- Use Accept: application/json header (already sent) and confirm no middleware alters the response
Example fix
// before
data = await resp.json();
// after
const text = await resp.text();
try {
data = JSON.parse(text);
} catch {
throw new CommandExecutionError(`hf spaces returned malformed JSON: ${text.slice(0, 120)}`);
} Defensive patterns
Strategy: type-guard
Validate before calling
// pre-flight content-type check on a probe request
const head = await fetch('https://huggingface.co/api/spaces?limit=1');
if (!(head.headers.get('content-type') || '').includes('application/json')) {
console.warn('HF response is not JSON — check proxy/interception');
} Type guard
function isJsonResponse(resp) {
return (resp.headers.get('content-type') || '').includes('application/json');
} Try / catch
try {
await hfSpaces(query);
} catch (e) {
if (String(e.message).includes('malformed JSON')) {
// inspect raw payload / retry once — often transient proxy corruption
return await withRetry(() => hfSpaces(query), 1);
}
throw e;
} Prevention
- Watch for captive portals/intercepting proxies returning HTML
- Always send Accept: application/json
- Log content-type and first bytes of unexpected bodies
- Retry once — corrupted responses are often transient
When it happens
Trigger: resp.json() throws: the server returned HTML (error/login page), an empty body with a 2xx status, truncated responses, or a proxy's plain-text error page instead of JSON.
Common situations: Captive portals or proxies intercepting HTTPS and returning HTML; HF returning 200 with an empty body during partial incidents; middleware rewriting responses.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- COMMAND_EXEC
- hf datasets returned malformed JSON: ${error?.message || err
- hf models returned malformed JSON: ${error?.message || error
- ${label} returned invalid JSON: ${outcome.detail}
- ${label} returned malformed JSON: ${err?.message ?? err}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d7ec7e7429d95647.
Report an issue: GitHub.