jackwener/OpenCLI · error · ArgumentError
${message}
Error message
${message} What it means
buildNoteUrl throws ArgumentError when given an xhslink.com short link while options.allowShortLink is false. Xiaohongshu note pages now require signed URLs (with xsec_token) for reliable access; short links are only accepted for download commands that opt in. The message names the command and the hint explains what URL format is accepted.
Source
Thrown at clis/xiaohongshu/note-helpers.js:56
*/
export function buildNoteUrl(input, options = {}) {
const {
allowShortLink = false,
commandName = 'xiaohongshu note',
cookieRoot = 'xiaohongshu.com',
signedUrlHint = XHS_SIGNED_URL_HINT,
} = options;
const trimmed = input.trim();
const message = `${commandName} now requires a full signed URL`;
const hint = allowShortLink
? `${signedUrlHint} For downloads, xhslink short links are also supported.`
: signedUrlHint;
if (/^https?:\/\//.test(trimmed)) {
if (isShortLink(trimmed)) {
if (allowShortLink)
return trimmed;
throw new ArgumentError(message, hint);
}
try {
const url = new URL(trimmed);
const xsecToken = url.searchParams.get('xsec_token')?.trim();
if (isHostMatch(url.hostname, cookieRoot) && isSupportedNotePath(url.pathname) && xsecToken) {
return trimmed;
}
}
catch { }
throw new ArgumentError(message, hint);
}
throw new ArgumentError(message, hint);
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Resolve the short link by opening it in a browser and copying the full www.xiaohongshu.com/explore/... URL including xsec_token.
- Get the note URL from search results or user-profile context so it carries xsec_token.
- If using the download command, verify you are on a code path that sets allowShortLink: true.
- Use the bare note ID only where the API still accepts it — for note detail it no longer resolves reliably.
Example fix
// before
buildNoteUrl('https://xhslink.com/a1B2c3');
// after
buildNoteUrl('https://www.xiaohongshu.com/explore/<id>?xsec_token=<token>', { commandName: 'xiaohongshu note' }); Defensive patterns
Strategy: validation
Validate before calling
const input = 'https://xhslink.com/a1B2c3';
if (/^https?:\/\/xhslink\.com\//i.test(input)) {
throw new Error('resolve the short link to a full xiaohongshu.com URL with xsec_token first');
} Type guard
function isFullSignedNoteUrl(input) {
if (/^https?:\/\/xhslink\.com\//i.test(input)) return false;
try {
const u = new URL(input);
return /(^|\.)xiaohongshu\.com$/.test(u.hostname)
&& /^\/(?:explore|note|search_result|discovery\/item)\/[a-f0-9]+/i.test(u.pathname)
&& !!u.searchParams.get('xsec_token')?.trim();
} catch { return false; }
} Try / catch
try {
await note(shortUrl);
} catch (err) {
if (err instanceof ArgumentError && err.message.includes('full signed URL')) {
console.error('Open the short link in a browser and pass the resolved URL with xsec_token.');
} else throw err;
} Prevention
- Never pass xhslink short links to note/comment commands — only downloads accept them.
- Always carry the xsec_token from the source page when copying URLs.
- Resolve short links once and store the expanded signed URL.
When it happens
Trigger: Calling a note command (e.g. 'xiaohongshu note <url>') with an https://xhslink.com/... URL when allowShortLink is false.
Common situations: Copying a share short link from the XHS app instead of the full note URL from search results; older scripts that predate the signed-URL requirement.
Related errors
- ${label} must be an integer between ${min} and ${max}, got $
- xiaohongshu/follow: invalid profile URL
- xiaohongshu/follow: profile URL must be an exact https://*.x
- xiaohongshu/follow: profile URL must be /user/profile/<userI
- xiaohongshu/follow: user-id must be a Xiaohongshu user ID (e
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4ce5abf3e6eafe63.
Report an issue: GitHub.