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

  1. Verify the userId is correct and matches /user/profile/<userId> on www.xiaohongshu.com.
  2. Open the profile URL manually in the logged-in Chrome session to confirm it resolves without redirects or captchas.
  3. Re-authenticate on www.xiaohongshu.com — a half-expired session can redirect to non-profile paths.
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/d46d8e32d23ae0db. Report an issue: GitHub.