jackwener/OpenCLI · error · CommandExecutionError

xiaohongshu/follow: malformed current-url payload

Error message

xiaohongshu/follow: malformed current-url payload

What it means

After navigating to the profile and settling, the command reads location.href via page.evaluate and requires it to be a plain string after unwrapEvaluateResult. A non-string result means the in-page evaluation did not return the expected value, so the command aborts with CommandExecutionError rather than acting on bad data.

Source

Thrown at clis/xiaohongshu/follow.js:180

            required: true,
            positional: true,
            help: 'User ID (e.g. 5d8f88dc0000000001005d3a) or profile URL',
        },
    ],
    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(

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command; transient context destruction usually resolves on retry.
  2. Log in to www.xiaohongshu.com in the connected browser so no redirect happens during settle.
  3. Increase the settle wait or close interfering dialogs/tabs on the profile page.
  4. Check the extension/daemon version and unwrapEvaluateResult handling if payloads are consistently non-strings.

Example fix

// before
const hrefRaw = unwrapEvaluateResult(await page.evaluate('() => location.href'));
if (typeof hrefRaw !== 'string') throw new CommandExecutionError('...malformed current-url payload');
// after
const hrefRaw = unwrapEvaluateResult(await page.evaluate('() => location.href'));
if (typeof hrefRaw !== 'string') {
  console.error('location.href evaluate returned:', hrefRaw); // inspect and handle wrapper
  throw new CommandExecutionError('...malformed current-url payload');
}
Defensive patterns

Strategy: retry

Type guard

function isString(x) { return typeof x === 'string'; }

Try / catch

try {
  await follow(page, userId);
} catch (err) {
  if (err.code === 'COMMAND_EXEC' && err.message.includes('malformed current-url')) {
    await sleep(1000);
    return follow(page, userId); // retry once after settle
  }
  throw err;
}

Prevention

When it happens

Trigger: The evaluate returned null/undefined (page navigated or context destroyed mid-run), an Error object from the page, or an object wrapper from the extension bridge that unwrapEvaluateResult couldn't flatten.

Common situations: The site redirected (login wall, captcha) while waiting PROFILE_SETTLE_MS, destroying the eval context; a JS dialog blocking evaluation; stale extension bridge after reconnect; site CSP changes breaking the injected script.

Understand the failure class

Related errors


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