jackwener/OpenCLI · error · CommandExecutionError

xiaohongshu creator-notes: captured ${items.length} of ${Mat

Error message

xiaohongshu creator-notes: captured ${items.length} of ${Math.min(total, limit)} expected analyze rows; refusing partial results

What it means

fetchCreatorNotesByCapture throws this CommandExecutionError when isAnalyzeCaptureComplete reports fewer analyze rows captured than expected (min(total, limit)). It deliberately refuses partial results rather than returning an incomplete table, because a silently truncated note list would be misleading.

Source

Thrown at clis/xiaohongshu/creator-notes.js:323

        if (!clicked) break;
        const before = items.length;
        let advanced = false;
        for (let attempt = 0; attempt < CAPTURE_POLL_ATTEMPTS; attempt++) {
            await page.wait(CAPTURE_POLL_INTERVAL_S);
            const raw = await page.evaluate('JSON.stringify(window.__xhsCapture || {})');
            captureMap = parseCaptureMapPayload(raw);
            const harvested = harvestAnalyzeListCaptures(captureMap);
            if (harvested.items.length > before) {
                items = harvested.items;
                total = Math.max(total, harvested.total);
                advanced = true;
                break;
            }
        }
        if (!advanced) break;
    }
    if (!isAnalyzeCaptureComplete(items, total, limit)) {
        throw new CommandExecutionError(`xiaohongshu creator-notes: captured ${items.length} of ${Math.min(total, limit)} expected analyze rows; refusing partial results`);
    }
    const notes = mapAnalyzeItems(items).slice(0, limit);
    const missingTitles = notes.filter((note) => !note.title).length;
    if (missingTitles > 0) {
        const titleMap = await fetchNoteManagerTitleMap(page, notes.length);
        for (const note of notes) {
            if (!note.title && note.id && titleMap.has(note.id)) {
                note.title = titleMap.get(note.id);
            }
        }
    }
    return notes;
}
async function fetchCreatorNotesByApi(page, limit) {
    const pageSize = Math.min(Math.max(limit, 10), 20);
    const maxPages = Math.max(1, Math.ceil(limit / pageSize));
    const notes = [];
    await page.goto(`https://creator.xiaohongshu.com/statistics/data-analysis?type=0&page_size=${pageSize}&page_num=1`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Lower the limit (e.g. 20 instead of 100) and paginate across multiple runs to avoid mid-run throttling.
  2. Re-run the command; transient risk-control or load issues often complete on retry.
  3. Confirm you stay logged in for the whole run and no redirect interrupted pagination.
  4. Add waits/retries in your wrapper between runs to reduce risk-control pressure.
  5. Update the CLI if Xiaohongshu changed the analyze endpoint's pagination or total semantics.

Example fix

// before
const notes = await run('xiaohongshu creator-notes', { limit: 100 });
// after
try {
  return await run('xiaohongshu creator-notes', { limit: 100 });
} catch (e) {
  if (/refusing partial results/.test(e.message)) {
    await sleep(5000);
    return await run('xiaohongshu creator-notes', { limit: 20 }); // smaller batch
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const limit = Number(kwargs.limit ?? 20);
if (limit > 100) throw new Error('large limits risk partial captures; paginate instead');

Try / catch

async function fetchAllNotes(totalWanted) {
  const out = [];
  for (let offset = 0; offset < totalWanted; offset += 20) {
    out.push(...await withRetry(() => run('xiaohongshu creator-notes', { limit: 20 })));
    await sleep(1500 + Math.random() * 1500);
  }
  return out.slice(0, totalWanted);
}

Prevention

When it happens

Trigger: The paginated analyze endpoint returned fewer items than total before the loop exhausted its advance attempts — e.g. risk control throttled later pages, the SPA stopped firing requests mid-pagination, or the dashboard reduced page size so the completion predicate never saw all rows.

Common situations: Large limits (e.g. limit 100 with few captured pages) hitting rate limiting; session degraded mid-run so later signed calls return empty; Xiaohongshu changed analyze pagination shape; slow dashboard where the poll/advance budget ran out before all pages loaded.

Related errors


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