{"record":{"id":"551a590783c3c87e","repo":"jackwener/OpenCLI","slug":"www-xiaohongshu-com","errorCode":null,"errorMessage":"www.xiaohongshu.com","messagePattern":"www\\.xiaohongshu\\.com","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/follow.js","lineNumber":189,"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/follow: 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/follow: 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/follow: expected profile ${userId}, got ${parsedHref.pathname}`,\n                );\n            }\n\n            const result = requireActionResult(\n                await page.evaluate(buildFollowScript()),\n                'follow-action',\n            );\n            if (!result.ok) {\n                throw new CommandExecutionError(\n                    `xiaohongshu/follow failed: ${result.reason ?? 'unknown reason'}`,\n                );\n            }\n            return [{ status: result.state, user_id: userId, url }];","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/follow.js#L171-L207","documentation":"AuthRequiredError (exit code 77, EX_NOPERM) is thrown when the final URL after navigation is a /login path — the site bounced the unauthenticated session to its login page. The domain www.xiaohongshu.com is the login target; the fix is to log in to that domain in the connected browser.","triggerScenarios":"Running follow while the browser profile's xiaohongshu.com session cookie is missing or expired, so the profile URL redirects to /login during the settle wait.","commonSituations":"Cookie expiration after weeks of no manual login; logging out in the connected Chrome profile; using a fresh/clean browser profile with no session; site forcing re-login after suspicious activity.","solutions":["Open Chrome/Chromium, go to https://www.xiaohongshu.com, and log in manually, then re-run the command.","Verify login by running a read-only xiaohongshu command (e.g. feed) before write actions like follow.","Ensure the CLI is using the browser profile where you are logged in (check the configured profile)."],"exampleFix":"// before\nopencli xiaohongshu follow --user-id 5d8f88dc0000000001005d3a\n// after\n# log in to https://www.xiaohongshu.com in the connected browser first\nopencli xiaohongshu follow --user-id 5d8f88dc0000000001005d3a","handlingStrategy":"try-catch","validationCode":"// pre-check login state before a write command\nconst onLogin = await page.evaluate('() => /\\\\/login(?:[/?#]|$)/i.test(location.pathname)');\nif (onLogin) throw new Error('Log in to www.xiaohongshu.com first');","typeGuard":"const isAuthRequired = (e) => e instanceof Error && e.code === 'AUTH_REQUIRED';","tryCatchPattern":"try {\n  await follow(page, userId);\n} catch (err) {\n  if (err.code === 'AUTH_REQUIRED') {\n    console.error('Open Chrome and log in to https://www.xiaohongshu.com, then retry.');\n    process.exitCode = 77;\n    return;\n  }\n  throw err;\n}","preventionTips":["Log in to xiaohongshu.com in the connected browser before write commands","Re-login when sessions expire (cookies last weeks, not forever)","Verify login with a read-only command before batch follow runs","Use the browser profile where you are actually logged in"],"tags":["auth-required","login","session-expired","xiaohongshu"],"backgroundTag":"auth-required-login-redirect","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}