jackwener/OpenCLI · error · CommandExecutionError

xiaohongshu/follow: expected Xiaohongshu profile host, got $

Error message

xiaohongshu/follow: expected Xiaohongshu profile host, got ${parsedHref.hostname}

What it means

After navigation the command asserts the browser actually landed on a https://*.xiaohongshu.com profile page; if the final URL's scheme or host differs, CommandExecutionError names the offending hostname. This catches redirects off-domain (security check: never act on a page that isn't Xiaohongshu).

Source

Thrown at clis/xiaohongshu/follow.js:184

    ],
    columns: ['status', 'user_id', 'url'],
    func: async (page, kwargs) => {
        if (!page) {
            throw new CommandExecutionError('Browser session required for xiaohongshu follow');
        }
        try {
            const userId = assertUserId(kwargs['user-id']);
            const url = `https://www.xiaohongshu.com/user/profile/${userId}`;
            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) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the profile URL manually in the connected browser and complete any verification/captcha, then re-run.
  2. Check the network for DNS/proxy hijacking; try a trusted network or VPN.
  3. Clear site cookies for xiaohongshu.com and log in fresh, then retry the follow command.
  4. If a legitimate new host pattern is being rejected, update isXiaohongshuHost in clis/xiaohongshu/follow.js.

Example fix

null
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await follow(page, userId);
} catch (err) {
  if (err.code === 'COMMAND_EXEC' && err.message.includes('expected Xiaohongshu profile host')) {
    // a redirect took the tab off-domain: complete any human verification, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: Xiaohongshu redirected the tab to a different domain (anti-bot gateway, regional mirror, telecom hijack page, or an error page on another host), or an http:// final URL after a redirect chain.

Common situations: Aggressive bot detection bouncing to a verification page on another host; DNS hijacking on untrusted networks; expired session landing on an SSO/redirector; corporate proxy rewriting URLs.

Related errors


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