jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu collection page returned malformed location
Error message
xiaohongshu collection page returned malformed location
What it means
assertOnCollectionProfile evaluates CURRENT_LOCATION_JS and requires the page to report its location as an object (hostname/pathname/href). A non-object result means the location probe failed or returned something unexpected, so CommandExecutionError is thrown. This validates navigation landed on a real page before path checks.
Source
Thrown at clis/xiaohongshu/collection-helpers.js:190
(() => ({
href: location.href,
hostname: location.hostname,
pathname: location.pathname,
}))()
`;
async function throwIfLoginWall(page) {
const payload = unwrapBrowserResult(await page.evaluate(LOGIN_WALL_JS));
if (payload === true) {
throw new AuthRequiredError('www.xiaohongshu.com', 'Xiaohongshu collection page requires login; re-login to xiaohongshu.com and retry.');
}
}
export async function assertOnCollectionProfile(page, userId) {
await throwIfLoginWall(page);
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)View on GitHub (pinned to 49907e53dc)
Solutions
- Ensure the page is fully loaded before calling fetchXhsCollectionNotes (wait for network idle)
- Check the browser/tab wasn't closed or navigated away mid-run
- Update the automation browser driver — stale evaluate contexts return undefined
- Add a retry that reloads the collection profile URL then re-asserts
Example fix
// before
const notes = await fetchXhsCollectionNotes(page, userId); // malformed location
// after
await page.goto(collectionUrl, { waitUntil: 'networkidle' });
if (page.isClosed()) throw new Error('page closed before scraping');
const notes = await fetchXhsCollectionNotes(page, userId); Defensive patterns
Strategy: try-catch
Validate before calling
if (page.isClosed?.()) throw new Error('page closed before location check');
const loc = await page.evaluate(() => ({ href: location.href }));
if (!loc || typeof loc !== 'object') await page.reload(); Type guard
const isLocation = (v) => v !== null && typeof v === 'object' && typeof v.href === 'string';
Try / catch
try { notes = await fetchXhsCollectionNotes(page, userId); } catch (e) { if (String(e.message).includes('malformed location')) { await page.goto(collectionUrl, { waitUntil: 'networkidle' }); notes = await fetchXhsCollectionNotes(page, userId); } else throw e; } Prevention
- Wait for networkidle/load before asserting page state
- Check page.isClosed() before evaluate calls
- Avoid navigating the page concurrently with scraping
- Pin compatible versions of the browser-automation wrapper
When it happens
Trigger: page.evaluate(CURRENT_LOCATION_JS) returns undefined/null (script failed, page navigated mid-eval, destroyed context) or unwrapBrowserResult yields a non-object (e.g. string error).
Common situations: Browser tab navigated or closed during scraping; CDP evaluation failed silently; heavy page redirects racing with the check; automation browser version mismatch breaking evaluate return values.
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
- UISDC news page returned an unreadable payload
- UISDC news selector drift: ${reason}
- Failed to extract UISDC news: ${getErrorMessage(error)}
- Upwork result at rank ${rank} did not include a valid cipher
- xiaohongshu collection API returned a malformed payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/94fe632ec71fe2a9.
Report an issue: GitHub.