jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu collection interceptor returned malformed…
Error message
xiaohongshu collection interceptor returned malformed captures
What it means
accumulateInterceptedNotes reads all captured network requests via page.getInterceptedRequests() and requires an array back. A non-array result means the interception API behaved unexpectedly (failed, wrong driver version, interception not installed), so CommandExecutionError is thrown. Without captures, no collection notes can be extracted.
Solutions
- Enable request interception before navigating to the collection page
- Confirm the page object is created by the same automation wrapper that defines getInterceptedRequests
- Log typeof result and its constructor to diagnose the driver's return shape after upgrades
- Re-run with a freshly launched browser — corrupted interception state can return undefined
Example fix
// before
await page.goto(url);
const rows = await accumulateInterceptedNotes(page, bucket, userId); // reqs undefined
// after
await page.enableRequestInterception([collectionApiPattern]); // must precede goto
await page.goto(url, { waitUntil: 'networkidle' });
const rows = await accumulateInterceptedNotes(page, bucket, userId); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof page.getInterceptedRequests !== 'function') throw new Error('interception unsupported: wrong page wrapper?');
const reqs = await page.getInterceptedRequests();
if (!Array.isArray(reqs)) throw new Error('interceptor returned ' + typeof reqs); Type guard
const isRequestArray = (v) => Array.isArray(v);
Try / catch
try { rows = await accumulateInterceptedNotes(page, bucket, userId); } catch (e) { if (String(e.message).includes('malformed captures')) { throw new Error('request interception not active — enable it before page.goto'); } throw e; } Prevention
- Enable network interception before any navigation
- Only pass page objects from the wrapper that implements getInterceptedRequests
- After driver upgrades, smoke-test that intercepted requests are returned as arrays
- Verify interception state on a fresh browser profile if undefined results appear
When it happens
Trigger: page.getInterceptedRequests() resolves to undefined/null or a non-array because request interception wasn't enabled before navigation, the page object isn't the automation wrapper's expected type, or the driver changed its return shape.
Common situations: Forgetting to enable network interception before page.goto; passing a raw puppeteer/playwright page where the wrapper expects its own extended page; upgrading the browser-automation library so getInterceptedRequests no longer exists/returns differently.
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
- xiaohongshu collection API returned a malformed payload
- Booking.com extractor returned an invalid status
- Booking.com extractor returned malformed items
- Booking.com page declared results but no property cards…
- Booking.com page returned no extractable data
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e38109f67e3c377a.
Report an issue: GitHub.
Appendix: source
Thrown at clis/xiaohongshu/collection-helpers.js:206
const payload = unwrapBrowserResult(await page.evaluate(CURRENT_LOCATION_JS));
if (!isObject(payload)) {
throw new CommandExecutionError('xiaohongshu collection page returned malformed location');
}
const hostname = toCleanString(payload.hostname).toLowerCase();
const pathname = toCleanString(payload.pathname);
if (hostname === 'www.xiaohongshu.com' && pathname === '/login') {
throw new AuthRequiredError('xiaohongshu collection page requires login');
}
const expectedPath = `/user/profile/${toCleanString(userId)}`;
if (hostname !== 'www.xiaohongshu.com' || pathname !== expectedPath) {
throw new CommandExecutionError(`xiaohongshu collection landed on unexpected page: ${toCleanString(payload.href) || `${hostname}${pathname}`}`);
}
}
async function accumulateInterceptedNotes(page, bucket, fallbackUserId) {
const reqs = await page.getInterceptedRequests();
if (!Array.isArray(reqs)) {
throw new CommandExecutionError('xiaohongshu collection interceptor returned malformed captures');
}
if (Array.isArray(reqs) && reqs.length > 0)
bucket.push(...reqs);
return extractNotesFromResponses(bucket, fallbackUserId);
}
export async function resolveXhsUserId(page, rawId) {
if (rawId)
return normalizeXhsUserId(String(rawId));
await page.goto('https://www.xiaohongshu.com/explore');
await page.wait(2);
await throwIfLoginWall(page);
const userId = unwrapBrowserResult(await page.evaluate(`() => {
const user = window.__INITIAL_STATE__?.user?.userInfo;
const info = user?._value ?? user ?? {};
return info.user_id || info.userId || info.userID || '';
}`));
const clean = toCleanString(userId);View on GitHub (pinned to 49907e53dc)