jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu collection DOM extraction returned malformed row
Error message
xiaohongshu collection DOM extraction returned malformed rows
What it means
extractNotesFromDom runs the EXTRACT_COLLECTION_DOM_JS script in the page and expects a JSON array back. If page.evaluate resolves to anything other than an array, the DOM extraction layer is considered broken and a CommandExecutionError is thrown.
Source
Thrown at clis/xiaohongshu/collection-helpers.js:234
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);
if (!clean) {
throw new AuthRequiredError('www.xiaohongshu.com', 'Not logged into Xiaohongshu (could not resolve current user id)');
}
return clean;
}
export async function extractNotesFromDom(page) {
const payload = unwrapBrowserResult(await page.evaluate(EXTRACT_COLLECTION_DOM_JS));
if (!Array.isArray(payload)) {
throw new CommandExecutionError('xiaohongshu collection DOM extraction returned malformed rows');
}
return payload.filter((item) => item?.id);
}
export async function fetchXhsCollectionNotes(page, {
userId,
profileTab,
apiPattern,
limit,
emptyLabel,
}) {
const capturedRequests = [];
await page.installInterceptor(apiPattern);
await page.goto(buildProfileCollectionUrl(userId, profileTab));
await page.wait(2);
await assertOnCollectionProfile(page, userId);
let notes = [];
for (let i = 0; i < 16; i++) {View on GitHub (pinned to 49907e53dc)
Solutions
- Ensure the collection page fully loaded (wait for the note grid selector) before calling extractNotesFromDom.
- Console-log the raw page.evaluate result to see what the script actually returned.
- Update EXTRACT_COLLECTION_DOM_JS to match the current XHS DOM structure.
- Add a null/undefined guard upstream or fall back to the API-based note fetch path.
Example fix
// before
if (!Array.isArray(payload)) throw new CommandExecutionError('...malformed rows');
// after
const raw = unwrapBrowserResult(await page.evaluate(EXTRACT_COLLECTION_DOM_JS));
if (!Array.isArray(payload)) {
console.error('DOM extraction returned:', raw);
throw new CommandExecutionError('...malformed rows');
} Defensive patterns
Strategy: type-guard
Validate before calling
const raw = await page.evaluate(EXTRACT_COLLECTION_DOM_JS);
const payload = unwrapBrowserResult(raw);
if (!Array.isArray(payload)) throw new Error(`DOM extraction returned ${typeof payload}`); Type guard
function isNoteRows(v) {
return Array.isArray(v) && v.every(i => i == null || typeof i === 'object');
} Try / catch
try {
const rows = await extractNotesFromDom(page);
} catch (e) {
if (e instanceof CommandExecutionError) {
await page.waitForSelector('.note-item', { timeout: 10000 }).catch(() => {});
return extractNotesFromDom(page);
}
throw e;
} Prevention
- Wait for the note grid to render before extracting.
- Log the raw evaluate result when extraction fails to spot DOM changes.
- Keep EXTRACT_COLLECTION_DOM_JS updated against XHS markup changes.
- Fall back to the API path when DOM extraction yields non-array data.
When it happens
Trigger: The injected script returns undefined/null or an object because the collection DOM did not render, a selector/structure change broke extraction, or unwrapBrowserResult passed through a non-array value.
Common situations: XHS updated its DOM so the in-page script's try/catch returns a sentinel object, the collection page failed to load, or a CSP/anti-bot mechanism interfered with evaluate.
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
- Failed to extract Booking.com cards: ${err?.message || err}
- coupang search extraction failed: ${error?.message || error}
- Failed to fetch Barchart greeks for ${symbol}
- Booking.com page returned no extractable data
- Booking.com extractor returned an invalid status
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8f6bc1042301ea3b.
Report an issue: GitHub.