jackwener/OpenCLI · error · ArgumentError
xiaohongshu/unfollow: invalid profile URL
Error message
xiaohongshu/unfollow: invalid profile URL
What it means
assertUserId validates the user-id argument for the xiaohongshu/unfollow CLI command. When the argument looks like a URL (starts with http:// or https://), it is parsed with new URL(); if parsing fails, this ArgumentError is thrown. It means the string passed as user-id was clearly intended to be a URL but is not a syntactically valid URL.
Source
Thrown at clis/xiaohongshu/unfollow.js:43
return host === 'xiaohongshu.com' || host.endsWith('.xiaohongshu.com');
}
function requireActionResult(payload, context) {
const inner = unwrapEvaluateResult(payload);
if (!inner || typeof inner !== 'object' || Array.isArray(inner) || typeof inner.ok !== 'boolean') {
throw new CommandExecutionError(`xiaohongshu/unfollow: malformed ${context} payload`);
}
return inner;
}
function assertUserId(raw) {
const input = String(raw ?? '').trim();
if (/^https?:\/\//i.test(input)) {
let parsed;
try {
parsed = new URL(input);
} catch {
throw new ArgumentError('xiaohongshu/unfollow: invalid profile URL');
}
if (parsed.protocol !== 'https:' || !isXiaohongshuHost(parsed.hostname)) {
throw new ArgumentError('xiaohongshu/unfollow: profile URL must be an exact https://*.xiaohongshu.com URL');
}
const match = parsed.pathname.match(/^\/user\/profile\/([a-zA-Z0-9]{8,32})\/?$/);
if (!match) {
throw new ArgumentError('xiaohongshu/unfollow: profile URL must be /user/profile/<userId>');
}
return match[1];
}
const userId = normalizeXhsUserId(raw);
if (!userId || !USER_ID_RE.test(userId)) {
throw new ArgumentError(
'xiaohongshu/unfollow: user-id must be a Xiaohongshu user ID (e.g. 5d8f88dc0000000001005d3a) or full profile URL',
);
}
return userId;
}View on GitHub (pinned to 49907e53dc)
Solutions
- Print the exact argument you are passing and re-copy the profile URL directly from the browser address bar, e.g. https://www.xiaohongshu.com/user/profile/5d8f88dc0000000001005d3a
- If you only have the user ID, drop the URL entirely and pass the bare ID (8-32 alphanumeric chars), e.g. xiaohongshu unfollow 5d8f88dc0000000001005d3a
- Check shell quoting (wrap the URL in single quotes) and trim whitespace/newlines before passing it
- Verify the URL scheme prefix is exactly http:// or https:// with two slashes
Example fix
// before $ xiaohongshu unfollow 'https//www.xiaohongshu.com/user/profile/5d8f88dc0000000001005d3a' // after $ xiaohongshu unfollow 'https://www.xiaohongshu.com/user/profile/5d8f88dc0000000001005d3a'
Defensive patterns
Strategy: validation
Validate before calling
const raw = String(arg ?? '').trim();
if (/^https?:\/\//i.test(raw)) { try { new URL(raw); } catch { throw new Error('Not a valid URL: ' + raw); } } Type guard
function looksLikeUrl(s) { return /^https?:\/\//i.test(String(s ?? '').trim()); }
function isValidUrl(s) { try { new URL(String(s).trim()); return true; } catch { return false; } } Try / catch
try { await cli.unfollow({ 'user-id': arg }); } catch (e) { if (String(e.message).includes('invalid profile URL')) { /* sanitize or ask for a corrected URL */ } else throw e; } Prevention
- Copy profile URLs directly from the browser address bar, not from chat/markdown
- Trim and single-quote URL arguments on the command line
- Validate URL syntax with new URL() before invoking the CLI
- Prefer passing the bare user ID when you have it
When it happens
Trigger: Passing a malformed URL string as the positional user-id argument, e.g. 'htp://www.xiaohongshu.com/user/profile/abc', 'https:/broken', or a URL with stray characters like 'https://www.xiaohongshu.com/user/profile/<id> ' containing quotes/brackets copied from markdown. The string must match /^https?:\/\//i to enter this branch.
Common situations: Copy-pasting a profile link from chat/docs where part of the URL got mangled (smart quotes, line breaks, missing slashes); programmatically building the URL with an uninitialized or interpolated variable (undefined), producing 'https://undefined/...'-like garbage; shell quoting stripping slashes.
Related errors
- --url must be a Discord channel URL like https://discord.com
- --url must be a Discord thread/post URL like https://discord
- id not a valid Grok URL (got "${input}")
- Invalid Instagram URL: ${raw}
- job-id must be a Midjourney UUID or https://www.midjourney.c
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/ae5b1cf8358b7905.
Report an issue: GitHub.