jackwener/OpenCLI · error · CommandExecutionError
Sina Finance rolling news API returned invalid JSON: ${error
Error message
Sina Finance rolling news API returned invalid JSON: ${error instanceof Error ? error.message : String(error)} What it means
CommandExecutionError thrown when response.json() rejects because the body is not valid JSON. The underlying parse error message is interpolated. This means the HTTP call succeeded but the body was HTML, empty, or otherwise non-JSON.
Source
Thrown at clis/sinafinance/rolling-news.js:86
num: '50',
page: '1',
});
let response;
try {
response = await fetch(`${ROLL_API}?${params}`);
}
catch (error) {
throw new CommandExecutionError(`Sina Finance rolling news request failed: ${error instanceof Error ? error.message : String(error)}`);
}
if (!response.ok) {
throw new CommandExecutionError(`Sina Finance rolling news API returned HTTP ${response.status}`);
}
let payload;
try {
payload = await response.json();
}
catch (error) {
throw new CommandExecutionError(`Sina Finance rolling news API returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`);
}
return normalizeRollRows(payload);
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Log the raw response text to see what was actually returned
- Check for proxy/VPN interference rewriting the body
- Retry — truncated bodies are often transient
- If Sina changed content-type/encoding, adjust the client's Accept headers
Example fix
// before
const text = await response.text();
console.log(text); // <html>... anti-bot page
// after
// disable interfering proxy or add browser-like headers
const res = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0', Referer: 'https://finance.sina.com.cn' } }); Defensive patterns
Strategy: try-catch
Try / catch
try {
const rows = await cli.rollingNews();
} catch (err) {
if (/invalid JSON/.test(err.message)) {
// body wasn't JSON: likely HTML error page or proxy interference
console.error('Non-JSON body from Sina; check proxy/anti-bot interception');
return retryWithBackoff(() => cli.rollingNews(), 2);
}
throw err;
} Prevention
- Bypass captive portals/proxies when calling the CLI
- Send browser-like headers (User-Agent, Referer) to avoid anti-bot HTML pages
- Retry on parse failures — truncation is often transient
- Log raw response text on failure to confirm what was returned
When it happens
Trigger: Sina (or a middlebox) returns an HTML error/login page with HTTP 200, an empty body, truncated responses, or gzip-encoding mismatches that make the body unparseable.
Common situations: Captive portals or proxies intercepting the response; Sina serving an anti-bot HTML page with status 200; CDN edge errors emitting partial bodies; network truncation on flaky connections.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${label} returned malformed JSON: ${err?.message ?? err}
- Chess.com callback returned malformed JSON for ${url}: ${err
- Chess.com API returned malformed JSON for ${url}: ${error?.m
- coingecko returned malformed JSON: ${error?.message || error
- ${label} returned malformed JSON: ${err?.message ?? err}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5240c15194027c57.
Report an issue: GitHub.