jackwener/OpenCLI · warning · EmptyResultError

Unexpected evaluate response

Error message

Unexpected evaluate response

What it means

After navigating to the note page and running NOTE_EXTRACT_JS via page.evaluate, the command expects an object result. If the evaluated script returns null, undefined, or a non-object, EmptyResultError('xiaohongshu/note', 'Unexpected evaluate response') is thrown — meaning the extraction script did not produce usable data rather than the note being missing.

Source

Thrown at clis/xiaohongshu/note.js:84

    name: 'note',
    access: 'read',
    description: '获取小红书笔记正文和互动数据',
    domain: 'www.xiaohongshu.com',
    strategy: Strategy.COOKIE,
    navigateBefore: false,
    args: [
        { name: 'note-id', required: true, positional: true, help: 'Full Xiaohongshu note URL with xsec_token' },
    ],
    columns: ['field', 'value'],
    func: async (page, kwargs) => {
        const raw = String(kwargs['note-id']);
        const noteId = parseNoteId(raw);
        const url = buildNoteUrl(raw, { commandName: 'xiaohongshu note' });
        await page.goto(url);
        await page.wait({ time: 2 + Math.random() * 3 });
        const data = await page.evaluate(NOTE_EXTRACT_JS);
        if (!data || typeof data !== 'object') {
            throw new EmptyResultError('xiaohongshu/note', 'Unexpected evaluate response');
        }
        if (data.securityBlock) {
            throw new CliError('SECURITY_BLOCK', 'Xiaohongshu security block: the note detail page was blocked by risk control.', /^https?:\/\//.test(raw)
                ? 'The page may be temporarily restricted. Try again later or from a different session.'
                : 'Try using a full URL from search results (with xsec_token) instead of a bare note ID.');
        }
        if (data.loginWall) {
            throw new AuthRequiredError('www.xiaohongshu.com', 'Note content requires login');
        }
        if (data.notFound) {
            throw new EmptyResultError('xiaohongshu/note', `Note ${noteId} not found or unavailable — it may have been deleted or restricted`);
        }
        const d = data;
        // XHS renders placeholder text like "赞"/"收藏"/"评论" when count is 0;
        // normalize to '0' unless the value looks numeric.
        const numOrZero = (v) => /^\d+/.test(v) ? v : '0';
        // A note may legitimately have no title, but a real note page always
        // renders an author. If both are missing, the page failed to load.

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry — a not-yet-hydrated page is the most common cause.
  2. Verify the URL renders a real note page in the logged-in browser.
  3. Check for security-block/login pages manually; if present the session needs attention.
  4. Regenerate a fresh URL with a valid xsec_token.

Example fix

// before
const data = await page.evaluate(NOTE_EXTRACT_JS); // too early
// after
await page.wait({ time: 4 });
const data = await page.evaluate(NOTE_EXTRACT_JS);
if (!data || typeof data !== 'object') throw new EmptyResultError('xiaohongshu/note', 'Unexpected evaluate response');
Defensive patterns

Strategy: retry

Validate before calling

// Nothing to pre-validate client-side; ensure the URL is a valid signed note URL first
if (!/[?&]xsec_token=/.test(raw)) console.warn('URL lacks xsec_token; extraction may fail');

Type guard

function isExtractPayload(v) {
  return !!v && typeof v === 'object' && !Array.isArray(v);
}

Try / catch

try {
  await note(url);
} catch (err) {
  if (err instanceof EmptyResultError && err.message.includes('Unexpected evaluate response')) {
    await sleep(3000);
    return note(url); // page likely hadn't hydrated
  } else throw err;
}

Prevention

When it happens

Trigger: page.evaluate(NOTE_EXTRACT_JS) returns a non-object — the extraction script bailed early because the page structure was unexpected, the page did not finish rendering, or evaluate returned a wrapped/unserializable value.

Common situations: Slow network so the SPA hadn't hydrated despite the 2-5s random wait; XHS A/B page variants where selectors don't match; risk-control serving a blank shell page; xsec_token expired producing an odd page state.

Related errors


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