jackwener/OpenCLI · error · CliError
PARSE_ERROR
PARSE_ERROR
Error message
Bloomberg Businessweek page returned malformed story data
What it means
The businessweek command scrapes Bloomberg's Businessweek page expecting Next.js __NEXT_DATA__/module data exposing story entries. This CliError with code PARSE_ERROR fires when the loaded result is not an object — i.e. the page loader returned nothing usable even after the NO_NEXT_DATA/NO_MODULES retry. It indicates the page structure or delivery changed rather than a user mistake.
Source
Thrown at clis/bloomberg/businessweek.js:107
${normalizeStoryPathSource}
${extractStoriesSource}
const el = document.getElementById('__NEXT_DATA__');
if (!el) return { ok: false, error: 'NO_NEXT_DATA', title: document.title };
let data;
try { data = JSON.parse(el.textContent); }
catch (err) { return { ok: false, error: 'BAD_NEXT_DATA', message: String(err) }; }
const stories = extractBusinessweekStoriesFromNextData(data);
if (!stories) return { ok: false, error: 'NO_MODULES' };
return { ok: true, stories };
})()`);
let result = await loadStories();
// Next.js sometimes hydrates slowly — retry once before giving up.
if (result && result.ok === false && (result.error === 'NO_NEXT_DATA' || result.error === 'NO_MODULES')) {
await page.wait(4);
result = await loadStories();
}
if (!result || typeof result !== 'object') {
throw new CliError('PARSE_ERROR', 'Bloomberg Businessweek page returned malformed story data', 'Bloomberg may have changed the page structure.');
}
if (result.ok === false) {
throw new CliError('PARSE_ERROR', `Bloomberg Businessweek page did not expose story data (${result.error})`, 'Bloomberg may have changed the page structure.');
}
const stories = Array.isArray(result.stories) ? result.stories : [];
if (!stories.length) {
throw new CliError('NOT_FOUND', 'No Bloomberg Businessweek stories found', 'Bloomberg may have changed the page structure.');
}
return stories.slice(0, count);
},
});
export const __test__ = {
command,
parseBusinessweekLimit,
normalizeBusinessweekStoryPath,
extractBusinessweekStoriesFromNextData,
};View on GitHub (pinned to 49907e53dc)
Solutions
- Retry later; slow hydration or transient interstitials often resolve
- Clear/retry with a real browser profile and accept Bloomberg's consent banner so the real page loads
- Inspect the served HTML to find where story data now lives and update loadStories() selectors in clis/bloomberg/businessweek.js
- Check for a CLI update — scrape-target changes are usually fixed upstream
- Use an alternate source (e.g. Bloomberg RSS) if scraping remains blocked
Example fix
// before
const stories = await getBusinessweekStories(page);
// after
try { const stories = await getBusinessweekStories(page); }
catch (e) {
if (e.code === 'PARSE_ERROR') console.error('Businessweek page layout changed or blocked; try again later or update the CLI');
else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
function isLoadResult(r) {
return !!r && typeof r === 'object' && !Array.isArray(r);
} Try / catch
try { const stories = await getBusinessweekStories(page); }
catch (e) {
if (e instanceof CliError && e.code === 'PARSE_ERROR') { console.error('Page layout changed or blocked; retry later or update selectors'); }
else throw e;
} Prevention
- Build in retries with waits for slow Next.js hydration
- Keep a real-browser profile and accept consent banners
- Alert on PARSE_ERROR to detect upstream page changes fast
- Maintain a fallback data source (e.g. RSS) for critical flows
When it happens
Trigger: loadStories() returns null/non-object after the initial attempt and one retry (page.wait(4) then reload) — e.g. the page served a consent/paywall wall, a bot-detection page, or the Next.js data hooks were renamed/removed by a Bloomberg site update.
Common situations: Bloomberg redesigns its Next.js frontend; a consent-cookie or paywall interstitial replaces the article list; bot detection blocks the headless browser; geo-blocking changes the served page.
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
- NOT_FOUND
- FETCH_ERROR
- PARSE_ERROR
- Failed to parse Jike user data: ${data.message || 'unknown e
- Could not parse profile data
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5b94814c9b7536ba.
Report an issue: GitHub.