{"record":{"id":"17178eab30912296","repo":"jackwener/OpenCLI","slug":"xiaohongshu-collection-landed-on-unexpected-page","errorCode":null,"errorMessage":"xiaohongshu collection landed on unexpected page: ${toCleanString(payload.href) || `${hostname}${pathname}`}","messagePattern":"xiaohongshu collection landed on unexpected page: (.+?)(.+?)`\\}","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/collection-helpers.js","lineNumber":199,"sourceCode":"    if (payload === true) {\n        throw new AuthRequiredError('www.xiaohongshu.com', 'Xiaohongshu collection page requires login; re-login to xiaohongshu.com and retry.');\n    }\n}\n\nexport async function assertOnCollectionProfile(page, userId) {\n    await throwIfLoginWall(page);\n    const payload = unwrapBrowserResult(await page.evaluate(CURRENT_LOCATION_JS));\n    if (!isObject(payload)) {\n        throw new CommandExecutionError('xiaohongshu collection page returned malformed location');\n    }\n    const hostname = toCleanString(payload.hostname).toLowerCase();\n    const pathname = toCleanString(payload.pathname);\n    if (hostname === 'www.xiaohongshu.com' && pathname === '/login') {\n        throw new AuthRequiredError('xiaohongshu collection page requires login');\n    }\n    const expectedPath = `/user/profile/${toCleanString(userId)}`;\n    if (hostname !== 'www.xiaohongshu.com' || pathname !== expectedPath) {\n        throw new CommandExecutionError(`xiaohongshu collection landed on unexpected page: ${toCleanString(payload.href) || `${hostname}${pathname}`}`);\n    }\n}\n\nasync function accumulateInterceptedNotes(page, bucket, fallbackUserId) {\n    const reqs = await page.getInterceptedRequests();\n    if (!Array.isArray(reqs)) {\n        throw new CommandExecutionError('xiaohongshu collection interceptor returned malformed captures');\n    }\n    if (Array.isArray(reqs) && reqs.length > 0)\n        bucket.push(...reqs);\n    return extractNotesFromResponses(bucket, fallbackUserId);\n}\n\nexport async function resolveXhsUserId(page, rawId) {\n    if (rawId)\n        return normalizeXhsUserId(String(rawId));\n    await page.goto('https://www.xiaohongshu.com/explore');\n    await page.wait(2);","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/collection-helpers.js#L181-L217","documentation":"assertOnCollectionProfile verifies the page landed on /user/profile/<userId> for the requested user. Any other location throws CommandExecutionError embedding the actual href (or hostname+pathname). This catches wrong navigations and unexpected redirects so scraping never reads another page's data.","triggerScenarios":"Navigation landed on the home feed, a verification page, a note detail page, or another user's profile — any hostname/path other than www.xiaohongshu.com + /user/profile/<userId>.","commonSituations":"Wrong userId passed in (typo or numeric id vs profile id); xiaohongshu redirecting to a risk-control/verify page; URL-building bug concatenating a bad path; locale prefix paths (e.g. /en/user/...) failing the exact match.","solutions":["Print the actual href from the error message and compare with the expected /user/profile/<userId> path","Verify the userId is the correct xiaohongshu profile identifier (from the profile URL, not the numeric uid)","Handle any risk-control/verification page before scraping","Fix your navigation URL construction to use the exact profile URL format"],"exampleFix":"// before\nawait page.goto(`https://www.xiaohongshu.com/user/profile/${uid}`); // uid = numeric DB id\n// after\nconst profileId = user.xhsProfileId; // id as it appears in the profile URL\nawait page.goto(`https://www.xiaohongshu.com/user/profile/${profileId}`);","handlingStrategy":"validation","validationCode":"const expected = `https://www.xiaohongshu.com/user/profile/${userId}`;\nif (page.url() !== expected) await page.goto(expected, { waitUntil: 'networkidle' });","typeGuard":"const onExpectedProfile = (url, userId) => { try { const u = new URL(url); return u.hostname === 'www.xiaohongshu.com' && u.pathname === `/user/profile/${userId}`; } catch { return false; } };","tryCatchPattern":"try { notes = await fetchXhsCollectionNotes(page, userId); } catch (e) { const m = String(e.message).match(/unexpected page: (\\S+)/); if (m) { console.error('landed on', m[1]); await page.goto(expectedUrl, { waitUntil: 'networkidle' }); notes = await fetchXhsCollectionNotes(page, userId); } else throw e; }","preventionTips":["Use the exact profile id from the profile URL, not internal numeric uids","Log and compare actual vs expected URL whenever navigation is involved","Handle risk-control/verification interstitials before scraping","Build navigation URLs from a single tested helper"],"tags":["scraping","navigation","url-mismatch","command-execution-error"],"backgroundTag":"unexpected-page-redirect","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}