{"record":{"id":"297dbf79cda98ca1","repo":"jackwener/OpenCLI","slug":"xiaohongshu-follow-profile-url-must-be-an-exact-h","errorCode":null,"errorMessage":"xiaohongshu/follow: profile URL must be an exact https://*.xiaohongshu.com URL","messagePattern":"xiaohongshu/follow: profile URL must be an exact https://\\*\\.xiaohongshu\\.com URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/follow.js","lineNumber":50,"sourceCode":"function requireActionResult(payload, context) {\n    const inner = unwrapEvaluateResult(payload);\n    if (!inner || typeof inner !== 'object' || Array.isArray(inner) || typeof inner.ok !== 'boolean') {\n        throw new CommandExecutionError(`xiaohongshu/follow: malformed ${context} payload`);\n    }\n    return inner;\n}\n\nfunction assertUserId(raw) {\n    const input = String(raw ?? '').trim();\n    if (/^https?:\\/\\//i.test(input)) {\n        let parsed;\n        try {\n            parsed = new URL(input);\n        } catch {\n            throw new ArgumentError('xiaohongshu/follow: invalid profile URL');\n        }\n        if (parsed.protocol !== 'https:' || !isXiaohongshuHost(parsed.hostname)) {\n            throw new ArgumentError('xiaohongshu/follow: profile URL must be an exact https://*.xiaohongshu.com URL');\n        }\n        const match = parsed.pathname.match(/^\\/user\\/profile\\/([a-zA-Z0-9]{8,32})\\/?$/);\n        if (!match) {\n            throw new ArgumentError('xiaohongshu/follow: profile URL must be /user/profile/<userId>');\n        }\n        return match[1];\n    }\n    const userId = normalizeXhsUserId(raw);\n    if (!userId || !USER_ID_RE.test(userId)) {\n        throw new ArgumentError(\n            'xiaohongshu/follow: user-id must be a Xiaohongshu user ID (e.g. 5d8f88dc0000000001005d3a) or full profile URL',\n        );\n    }\n    return userId;\n}\n\n/**\n * The injected page script. Lives in the browser context, so it can't import","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/follow.js#L32-L68","documentation":"assertUserId enforces that a URL-form argument is an exact https URL on a xiaohongshu.com host (or subdomain). http:// URLs, other hosts (e.g. xhslink.com short links or mirror domains), are rejected with ArgumentError to prevent following on the wrong domain or an insecure scheme.","triggerScenarios":"Passing http:// instead of https://, or a profile URL on a non-Xiaohongshu domain (short link xhslink.com, a redirector, or a phishy mirror) to the follow command's --user-id option.","commonSituations":"Sharing links copied from third-party aggregators; using the share-sheet short link instead of the canonical www.xiaohongshu.com URL; older http bookmarks; enterprise proxies rewriting schemes.","solutions":["Use the canonical https URL on a xiaohongshu.com domain: https://www.xiaohongshu.com/user/profile/<userId>.","Resolve short links (xhslink.com) in a browser first, then copy the final xiaohongshu.com URL.","Or skip the URL entirely and pass the raw user ID extracted from the profile page."],"exampleFix":"// before\nopencli xiaohongshu follow --user-id 'http://www.xiaohongshu.com/user/profile/5d8f88dc0000000001005d3a'\n// after\nopencli xiaohongshu follow --user-id 'https://www.xiaohongshu.com/user/profile/5d8f88dc0000000001005d3a'","handlingStrategy":"validation","validationCode":"function isCanonicalXhsProfileUrl(raw) {\n  try {\n    const u = new URL(String(raw));\n    return u.protocol === 'https:' &&\n      (u.hostname === 'xiaohongshu.com' || u.hostname.endsWith('.xiaohongshu.com'));\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await opencliFollow(url);\n} catch (err) {\n  if (err.code === 'ARGUMENT' && err.message.includes('https://*.xiaohongshu.com')) {\n    // resolve short links / fix scheme, then retry\n  }\n  throw err;\n}","preventionTips":["Never pass http:// or short-link domains (xhslink.com)","Resolve short links in a browser first and use the final canonical URL","Validate scheme and host before invoking the CLI"],"tags":["argument-validation","url-validation","security","xiaohongshu"],"backgroundTag":"invalid-url-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}