jackwener/OpenCLI · error · CommandExecutionError

xiaohongshu/follow failed: ${err?.message ?? String(err)}

Error message

xiaohongshu/follow failed: ${err?.message ?? String(err)}

What it means

Catch-all wrapper: any non-CliError thrown inside the follow command's try block is rethrown as CommandExecutionError with the prefix 'xiaohongshu/follow failed:' plus the original message. It preserves the underlying cause's message while normalizing the error type for the CLI. CliError instances pass through untouched.

Source

Thrown at clis/xiaohongshu/follow.js:210

            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)}`,
            );
        }
    },
});

export const __test__ = {
    assertUserId,
    buildFollowScript,
};

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect the embedded err.message after the prefix to find the root cause.
  2. Reopen Chrome and ensure the target tab/page object is alive before rerunning.
  3. Retry the command; transient browser/navigation issues are the usual cause.
  4. If it persists, run with verbose logging to capture the original stack.

Example fix

// before
// page closed before evaluate
await follow(userId);
// after
const page = await ensureBrowserPage(); // keep page alive
await page.goto(profileUrl);
await follow(userId);
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the browser/page is alive before the command
if (page.isClosed?.()) throw new Error('target page closed before follow');

Type guard

function isWrappedFollowError(err) {
  return err instanceof Error && err.message.startsWith('xiaohongshu/follow failed:');
}

Try / catch

try {
  await follow(userId);
} catch (err) {
  if (isWrappedFollowError(err)) {
    const cause = err.message.replace('xiaohongshu/follow failed: ', '');
    console.error('underlying cause:', cause);
  } else throw err;
}

Prevention

When it happens

Trigger: Any unexpected exception during the follow flow that is not a CliError — e.g. page.evaluate threw (page closed/navigated away), requireActionResult detected a malformed payload indirectly? no (that throws CommandExecutionError directly, which is a CliError and passes through) — realistically evaluate failures, timeouts, or browser disconnection.

Common situations: Chrome tab closed mid-run; navigation interrupted; evaluate returned an unserializable value; random wait interrupted by page crash.

Related errors


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