jackwener/OpenCLI · error · CommandExecutionError
Reuters search returned a non-JSON body${detail}
Error message
Reuters search returned a non-JSON body${detail} What it means
CommandExecutionError thrown when the Reuters search API responded but the body could not be produced as JSON (result.body is falsy). If the page script captured a parseError, it is appended to the message. The remediation hint tells the user to open www.reuters.com and clear any challenge before retrying, because Datadome often returns HTML challenge pages instead of JSON.
Source
Thrown at clis/reuters/search.js:52
}
if (!result || typeof result !== 'object') {
throw new CommandExecutionError('Reuters search API returned an unreadable response');
}
if (isAuthStatus(result.status) || looksAuthWallText(result.textPreview)) {
throw new AuthRequiredError(
'www.reuters.com',
`Reuters search requires an accessible Reuters browser session or completed human verification${result.status ? ` (HTTP ${result.status})` : ''}`,
);
}
if (result.ok !== true) {
const status = Number.isFinite(result.status) && result.status > 0
? `HTTP ${result.status}${result.statusText ? ` ${result.statusText}` : ''}`
: 'no upstream response';
throw new CommandExecutionError(`Reuters search API failed (${status})`);
}
if (!result.body) {
const detail = result.parseError ? `: ${result.parseError}` : '';
throw new CommandExecutionError(
`Reuters search returned a non-JSON body${detail}`,
'Open www.reuters.com in your browser and clear any challenge before retrying.',
);
}
const rows = mapSearchArticles(result.body, limit);
if (!rows.length) {
throw new EmptyResultError('reuters search', `No articles matched "${query}". Try broadening the query.`);
}
return rows;
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Open www.reuters.com in the browser session, complete any challenge, then retry (per the error's own hint).
- Re-run the search — challenge pages are often one-off interstitials.
- If parseError mentions a schema/field mismatch, update buildSearchScript/mapSearchArticles in clis/reuters/utils.js to match Reuters' new response format.
- Check the logged parseError detail to distinguish a challenge page from a format change.
Example fix
// before
const result = await page.evaluate(buildSearchScript(query, limit));
// after: detect HTML challenge body before parsing
const ct = resp.headers.get('content-type') || '';
const text = await resp.text();
if (!ct.includes('json') || /<html/i.test(text)) return { ok: true, parseError: 'non-JSON body (challenge page?)' };
return { ok: true, body: JSON.parse(text) }; Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm the tab serves JSON, not a challenge page
const probe = await page.evaluate(() => fetch('/api?probe=1').then(r => r.headers.get('content-type')).catch(() => ''));
if (!probe.includes('json')) throw new Error('Reuters is serving non-JSON (challenge?) — clear it in the browser first'); Type guard
function hasParsedBody(result) {
return typeof result === 'object' && result !== null && result.ok === true &&
result.body !== null && typeof result.body === 'object' && !result.parseError;
} Try / catch
try {
const rows = await cli.run('reuters search', { query });
} catch (e) {
if (e.message.includes('non-JSON body')) {
await clearChallengeInBrowser('https://www.reuters.com');
return cli.run('reuters search', { query });
}
throw e;
} Prevention
- Clear Datadome challenges promptly; don't reuse a challenged session.
- Check content-type in the in-page fetch before JSON.parse and capture parseError detail.
- Re-validate the mapper after any Reuters API response-format change.
- Retry once on this error — challenge interstitials are frequently transient.
When it happens
Trigger: The in-page fetch returned ok:true but response.json() failed or returned nothing — typically the response was an HTML Datadome challenge page, an empty body, or Reuters changed the response format.
Common situations: Datadome serving an interstitial HTML page that still returns 200; empty 204/HTML responses from an edge cache; Reuters shipping a new response schema breaking the parser; compressed/undecodable responses in the tab context.
Related errors
- archive search returned malformed JSON: ${error?.message ||
- archive wayback returned malformed JSON: ${error?.message ||
- ${label} returned malformed JSON: ${err?.message ?? err}
- eastmoney convertible returned invalid JSON: ${error?.messag
- hf models returned malformed JSON: ${error?.message || error
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/459be303aa63820c.
Report an issue: GitHub.