jackwener/OpenCLI · error · CommandExecutionError

xiaohongshu collection interceptor returned malformed captur

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.

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)

Solutions

  1. Enable request interception before navigating to the collection page
  2. Confirm the page object is created by the same automation wrapper that defines getInterceptedRequests
  3. Log typeof result and its constructor to diagnose the driver's return shape after upgrades
  4. 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

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

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/e38109f67e3c377a. Report an issue: GitHub.