{"record":{"id":"a7f071abf171331e","repo":"jackwener/OpenCLI","slug":"www-xiaohongshu-com-a7f071","errorCode":null,"errorMessage":"www.xiaohongshu.com","messagePattern":"www\\.xiaohongshu\\.com","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/unfollow.js","lineNumber":220,"sourceCode":"        }\n        try {\n            const userId = assertUserId(kwargs['user-id']);\n            const url = `https://www.xiaohongshu.com/user/profile/${userId}`;\n            await page.goto(url);\n            await page.wait({ time: PROFILE_SETTLE_MS / 1000 });\n\n            const hrefRaw = unwrapEvaluateResult(await page.evaluate('() => location.href'));\n            if (typeof hrefRaw !== 'string') {\n                throw new CommandExecutionError('xiaohongshu/unfollow: malformed current-url payload');\n            }\n            const parsedHref = new URL(hrefRaw);\n            if (parsedHref.protocol !== 'https:' || !isXiaohongshuHost(parsedHref.hostname)) {\n                throw new CommandExecutionError(\n                    `xiaohongshu/unfollow: expected Xiaohongshu profile host, got ${parsedHref.hostname}`,\n                );\n            }\n            if (/\\/login(?:[/?#]|$)/i.test(parsedHref.pathname)) {\n                throw new AuthRequiredError('www.xiaohongshu.com');\n            }\n            const currentProfile = parsedHref.pathname.match(/^\\/user\\/profile\\/([a-zA-Z0-9]{8,32})\\/?$/);\n            if (currentProfile?.[1] !== userId) {\n                throw new CommandExecutionError(\n                    `xiaohongshu/unfollow: expected profile ${userId}, got ${parsedHref.pathname}`,\n                );\n            }\n\n            // Step 1: click 已关注 (idempotent — bails out if 关注 is visible)\n            const clickResult = requireActionResult(\n                await page.evaluate(buildClickUnfollowScript()),\n                'click-unfollow',\n            );\n            if (!clickResult.ok) {\n                throw new CommandExecutionError(\n                    `xiaohongshu/unfollow failed: ${clickResult.reason ?? 'unknown reason'}`,\n                );\n            }","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/unfollow.js#L202-L238","documentation":"AuthRequiredError('www.xiaohongshu.com') is thrown when the final page URL is on xiaohongshu.com but its path looks like a login page (/login...). The site redirected the browser to login because the session cookies are missing, expired, or invalid, so the unfollow action cannot proceed unauthenticated.","triggerScenarios":"Cookie session expired or was invalidated (logged out elsewhere, password change); the automated Chrome profile was never logged in; cookies cleared between runs; the site forces re-login due to risk control; Strategy.COOKIE session synced stale/expired cookies.","commonSituations":"Long-lived automation environments where the session silently expired; switching Chrome profiles; running after xiaohongshu logged the account out for security reasons; running two sessions that invalidate each other's cookies.","solutions":["Log into www.xiaohongshu.com in the automated Chrome browser (scan the QR code) and re-run the command","Refresh/sync the cookie session used by the CLI (re-export cookies from a logged-in browser)","Check the account in a normal browser: if you were logged out or restricted, recover the login first","Re-run after completing any risk-control verification the site showed"],"exampleFix":"// before: run with expired cookies\n$ xiaohongshu unfollow <id>   # -> AuthRequiredError('www.xiaohongshu.com')\n// after: re-login in the automated Chrome, then\n$ xiaohongshu unfollow <id>","handlingStrategy":"try-catch","validationCode":"// verify cookies exist before running\nconst hasSession = document.cookie.includes('web_session'); // run inside the xiaohongshu browser context","typeGuard":null,"tryCatchPattern":"try { await cli.unfollow({ 'user-id': id }); } catch (e) { if (e.name === 'AuthRequiredError' || String(e.message) === 'www.xiaohongshu.com') { await loginFlow(); /* re-login then retry */ } else throw e; }","preventionTips":["Re-login (QR scan) whenever the session is refreshed or expired","Persist and reuse a logged-in Chrome profile for automation","Detect AuthRequiredError early and run the login flow automatically","Avoid running duplicate sessions that invalidate each other's cookies"],"tags":["auth","session","cookies","login"],"backgroundTag":"auth-required-login-redirect","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}