jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu collection API returned a note without stable id
Error message
xiaohongshu collection API returned a note without stable id/xsec token
What it means
Each mapped note row must have a stable id and a URL containing xsec_token, which the library needs to open notes reliably later. If mapCollectionNote yields a row missing id or lacking an xsec_token query parameter, CommandExecutionError is thrown. This prevents emitting rows that would fail on subsequent detail-page access.
Source
Thrown at clis/xiaohongshu/collection-helpers.js:103
export function extractNotesFromResponses(requests, fallbackUserId) {
const rows = [];
const seen = new Set();
for (const req of requests ?? []) {
const payload = unwrapBrowserResult(req);
if (!isObject(payload)) {
throw new CommandExecutionError('xiaohongshu collection API returned a malformed payload');
}
const data = payload.data;
if (!isObject(data)) {
throw new CommandExecutionError('xiaohongshu collection API returned malformed data');
}
const notes = data.notes ?? data.note_list;
if (!Array.isArray(notes))
throw new CommandExecutionError('xiaohongshu collection API returned malformed notes');
for (const entry of notes) {
const row = mapCollectionNote(entry, { fallbackUserId });
if (!row?.id || !row.url.includes('xsec_token=')) {
throw new CommandExecutionError('xiaohongshu collection API returned a note without stable id/xsec token');
}
if (seen.has(row.id))
continue;
seen.add(row.id);
rows.push(row);
}
}
return rows;
}
export const EXTRACT_COLLECTION_DOM_JS = `
(() => {
const normalizeUrl = (href) => {
if (!href) return '';
let url;
try {
url = new URL(href, 'https://www.xiaohongshu.com');
} catch {View on GitHub (pinned to 49907e53dc)
Solutions
- Skip/drop offending entries instead of aborting: pre-filter notes whose entry lacks id or xsec_token before calling extractNotesFromResponses
- Refresh login — restricted visibility can hide fields
- Inspect the raw entry JSON to find where id/xsec_token now live and update mapping
- Retry later if entries were transiently incomplete
Example fix
// before
const rows = extractNotesFromResponses(reqs, userId); // throws on one bad entry
// after
const cleaned = reqs.map(req => {
const p = req.json;
const notes = p?.data?.notes ?? p?.data?.note_list ?? [];
return { ...p, data: { ...p.data, notes: notes.filter(n => n.id && String(n.url ?? '').includes('xsec_token=')) } };
});
const rows = extractNotesFromResponses(cleaned, userId); Defensive patterns
Strategy: validation
Validate before calling
const usable = (entry) => entry && (entry.id ?? entry.note_id) && String(entry.url ?? entry.note_url ?? '').includes('xsec_token=');
// pre-filter entries before extraction so one bad note doesn't abort the run Type guard
const hasStableIdAndToken = (row) => typeof row?.id === 'string' && row.id.length > 0 && typeof row.url === 'string' && row.url.includes('xsec_token='); Try / catch
try { rows = extractNotesFromResponses(reqs, userId); } catch (e) { if (String(e.message).includes('xsec token')) { console.warn('skipping notes missing xsec_token'); rows = partialExtract(reqs, userId); } else throw e; } Prevention
- Pre-filter note entries lacking id or xsec_token before extraction
- Refresh login — restricted sessions omit token fields
- Inspect raw entry JSON when the schema drifts and update mapping
- Deduplicate by id to avoid relying on unstable entries
When it happens
Trigger: A note entry in the API response lacks its note_id or its url/xsec_token field — e.g. deleted/hidden notes, partially populated entries, or a mapping change in mapCollectionNote's source fields.
Common situations: Scraping a collection containing notes the session cannot fully see (restricted or removed notes); xiaohongshu omitting xsec_token on some list entries; version change in the entry schema (e.g. nested note objects).
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Upwork result at rank ${rank} did not include a valid cipher
- Booking.com hotel row is missing stable name/url identity
- IMDb redirected to a different title: ${currentId}
- UISDC news page returned an unreadable payload
- UISDC news selector drift: ${reason}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3d7b4455bf952e06.
Report an issue: GitHub.