jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu/follow: expected profile ${userId}, got ${parsed
Error message
xiaohongshu/follow: expected profile ${userId}, got ${parsedHref.pathname} What it means
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.
Source
Thrown at clis/xiaohongshu/follow.js:193
await page.goto(url);
await page.wait({ time: PROFILE_SETTLE_MS / 1000 });
const hrefRaw = unwrapEvaluateResult(await page.evaluate('() => location.href'));
if (typeof hrefRaw !== 'string') {
throw new CommandExecutionError('xiaohongshu/follow: malformed current-url payload');
}
const parsedHref = new URL(hrefRaw);
if (parsedHref.protocol !== 'https:' || !isXiaohongshuHost(parsedHref.hostname)) {
throw new CommandExecutionError(
`xiaohongshu/follow: expected Xiaohongshu profile host, got ${parsedHref.hostname}`,
);
}
if (/\/login(?:[/?#]|$)/i.test(parsedHref.pathname)) {
throw new AuthRequiredError('www.xiaohongshu.com');
}
const currentProfile = parsedHref.pathname.match(/^\/user\/profile\/([a-zA-Z0-9]{8,32})\/?$/);
if (currentProfile?.[1] !== userId) {
throw new CommandExecutionError(
`xiaohongshu/follow: expected profile ${userId}, got ${parsedHref.pathname}`,
);
}
const result = requireActionResult(
await page.evaluate(buildFollowScript()),
'follow-action',
);
if (!result.ok) {
throw new CommandExecutionError(
`xiaohongshu/follow failed: ${result.reason ?? 'unknown reason'}`,
);
}
return [{ status: result.state, user_id: userId, url }];
} catch (err) {
if (err instanceof CliError) throw err;
throw new CommandExecutionError(
`xiaohongshu/follow failed: ${err?.message ?? String(err)}`,View on GitHub (pinned to 49907e53dc)
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.
Example fix
// before
await follow('abc123'); // too short / wrong id
// after
await follow('5ff0e6410000000001008400'); // full 24-hex userId copied from the profile URL Defensive patterns
Strategy: validation
Validate before calling
const userId = '5ff0e6410000000001008400';
if (!/^[a-zA-Z0-9]{8,32}$/.test(userId)) throw new Error('invalid userId');
const url = `https://www.xiaohongshu.com/user/profile/${userId}`;
if (!/^\/user\/profile\/[a-zA-Z0-9]{8,32}\/?$/.test(new URL(url).pathname)) throw new Error('bad profile path'); Type guard
function isValidProfilePath(pathname, userId) {
const m = pathname.match(/^\/user\/profile\/([a-zA-Z0-9]{8,32})\/?$/);
return m?.[1] === userId;
} Try / catch
try {
await follow(userId);
} catch (err) {
if (err instanceof CommandExecutionError && err.message.includes('expected profile')) {
console.error('Redirected away from profile; check session/userId:', err.message);
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to load Booking.com search page: ${err?.message || er
- Failed to open Chess.com analysis board: ${error?.message ||
- coupang add-to-cart navigation failed: ${error?.message || e
- coupang search location evaluation failed: ${error?.message
- coupang search filtered navigation failed: ${error?.message
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d46d8e32d23ae0db.
Report an issue: GitHub.