jackwener/OpenCLI · error · CommandExecutionError
xiaohongshu/unfollow: expected profile ${userId}, got ${pars
Error message
xiaohongshu/unfollow: expected profile ${userId}, got ${parsedHref.pathname} What it means
After reaching the profile page, the command re-checks that the URL still identifies the requested user's profile (/user/profile/<same id>). If the final pathname does not match the requested userId (redirect to another profile, home page, 404, or a modified URL), this CommandExecutionError reporting the expected ID and actual pathname is thrown.
Source
Thrown at clis/xiaohongshu/unfollow.js:224
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/unfollow: malformed current-url payload');
}
const parsedHref = new URL(hrefRaw);
if (parsedHref.protocol !== 'https:' || !isXiaohongshuHost(parsedHref.hostname)) {
throw new CommandExecutionError(
`xiaohongshu/unfollow: 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/unfollow: expected profile ${userId}, got ${parsedHref.pathname}`,
);
}
// Step 1: click 已关注 (idempotent — bails out if 关注 is visible)
const clickResult = requireActionResult(
await page.evaluate(buildClickUnfollowScript()),
'click-unfollow',
);
if (!clickResult.ok) {
throw new CommandExecutionError(
`xiaohongshu/unfollow failed: ${clickResult.reason ?? 'unknown reason'}`,
);
}
if (clickResult.state === 'not-following') {
return [{ status: 'not-following', user_id: userId, url }];
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the user ID is correct and the profile loads in a normal browser (no redirect) before re-running
- Increase tolerance for slow loads: retry the command so the SPA finishes redirecting before the check
- Complete any captcha/risk-control challenge shown in the automated browser, then retry
- If the account no longer exists, treat the target as gone instead of retrying
Example fix
// before $ xiaohongshu unfollow 000000000000000000000000 # deleted user, redirects to / // after: confirm the profile URL opens in a browser first $ xiaohongshu unfollow 5d8f88dc0000000001005d3a
Defensive patterns
Strategy: validation
Validate before calling
// verify the target profile exists and does not redirect before automating
const res = await fetch(`https://www.xiaohongshu.com/user/profile/${id}`, { redirect: 'manual', headers: { 'user-agent': 'Mozilla/5.0' } });
if (res.status >= 300 && res.status < 400) throw new Error('Profile redirects — ID may be invalid/deleted'); Type guard
function expectProfilePath(href, userId) { try { return new URL(href).pathname.match(/^\/user\/profile\/([a-zA-Z0-9]{8,32})\/?$/)?.[1] === userId; } catch { return false; } } Try / catch
try { await cli.unfollow({ 'user-id': id }); } catch (e) { if (/expected profile /.test(String(e.message))) { /* validate the ID / confirm profile exists, then retry once */ } else throw e; } Prevention
- Confirm the profile opens without redirect in a normal browser before automating
- Keep IDs from a trusted source and re-validate stale records
- Retry once on slow networks so the SPA finishes redirecting before href is sampled
- Clear captcha/risk-control states before retrying
When it happens
Trigger: The profile ID does not exist or was deleted, so xiaohongshu redirects (e.g. to home or an error page); the account is banned/private and the site bounces to another route; the ID passed had casing/characters that got normalized differently; slow SPA redirect after settle time; a bot-detection redirect to a generic route.
Common situations: Unfollowing a user who deleted/deactivated their account; typo or stale ID from an old database; page still mid-redirect when location.href was sampled (settle time too short on a slow network); risk-control redirect after too many automated actions.
Related errors
- xiaohongshu/unfollow: expected Xiaohongshu profile host, got
- xiaohongshu/unfollow failed: ${clickResult.reason ?? 'unknow
- 1688 ${action} navigation lost the current browser target
- Could not find Antigravity input box
- Could not find input box
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a0529aa30a3210e2.
Report an issue: GitHub.