{"record":{"id":"d46d8e32d23ae0db","repo":"jackwener/OpenCLI","slug":"xiaohongshu-follow-expected-profile-userid-go","errorCode":null,"errorMessage":"xiaohongshu/follow: expected profile ${userId}, got ${parsedHref.pathname}","messagePattern":"xiaohongshu/follow: expected profile (.+?), got (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/follow.js","lineNumber":193,"sourceCode":"            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 }];\n        } catch (err) {\n            if (err instanceof CliError) throw err;\n            throw new CommandExecutionError(\n                `xiaohongshu/follow failed: ${err?.message ?? String(err)}`,","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/follow.js#L175-L211","documentation":"Thrown by the xiaohongshu follow command after navigating to a user's profile page. The command verifies the browser actually landed on /user/profile/<userId> for the requested user; if the URL pathname does not match the expected profile ID, it assumes navigation went somewhere unexpected and throws CommandExecutionError. This guards against following the wrong user or a redirected/blocked page.","triggerScenarios":"page.goto to the profile URL resolves to a different pathname than /user/profile/<userId> — e.g. XHS redirected to a login-adjacent or error page whose path is not /login (so the AuthRequiredError check above does not fire), or the userId passed does not match the profile the browser actually rendered.","commonSituations":"Stale or mistyped userId; XHS serving an interstitial/captcha page with an unusual path; mobile/region redirect variants of the profile URL; userId containing characters that get normalized away so the rendered profile differs.","solutions":["Verify the userId is correct and matches /user/profile/<userId> on www.xiaohongshu.com.","Open the profile URL manually in the logged-in Chrome session to confirm it resolves without redirects or captchas.","Re-authenticate on www.xiaohongshu.com — a half-expired session can redirect to non-profile paths.","Retry later if XHS is serving risk-control interstitials."],"exampleFix":"// before\nawait follow('abc123'); // too short / wrong id\n// after\nawait follow('5ff0e6410000000001008400'); // full 24-hex userId copied from the profile URL","handlingStrategy":"validation","validationCode":"const userId = '5ff0e6410000000001008400';\nif (!/^[a-zA-Z0-9]{8,32}$/.test(userId)) throw new Error('invalid userId');\nconst url = `https://www.xiaohongshu.com/user/profile/${userId}`;\nif (!/^\\/user\\/profile\\/[a-zA-Z0-9]{8,32}\\/?$/.test(new URL(url).pathname)) throw new Error('bad profile path');","typeGuard":"function isValidProfilePath(pathname, userId) {\n  const m = pathname.match(/^\\/user\\/profile\\/([a-zA-Z0-9]{8,32})\\/?$/);\n  return m?.[1] === userId;\n}","tryCatchPattern":"try {\n  await follow(userId);\n} catch (err) {\n  if (err instanceof CommandExecutionError && err.message.includes('expected profile')) {\n    console.error('Redirected away from profile; check session/userId:', err.message);\n  } else throw err;\n}","preventionTips":["Copy userId directly from the profile URL, not from display names.","Ensure the Chrome session is logged in before running follow.","Manually open the profile URL once to confirm it does not redirect or captcha."],"tags":["xiaohongshu","navigation","browser-automation"],"backgroundTag":"unexpected-redirect-url-mismatch","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}