{"record":{"id":"ae5b1cf8358b7905","repo":"jackwener/OpenCLI","slug":"xiaohongshu-unfollow-invalid-profile-url","errorCode":null,"errorMessage":"xiaohongshu/unfollow: invalid profile URL","messagePattern":"xiaohongshu/unfollow: invalid profile URL","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/unfollow.js","lineNumber":43,"sourceCode":"    return host === 'xiaohongshu.com' || host.endsWith('.xiaohongshu.com');\n}\n\nfunction 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/unfollow: 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/unfollow: invalid profile URL');\n        }\n        if (parsed.protocol !== 'https:' || !isXiaohongshuHost(parsed.hostname)) {\n            throw new ArgumentError('xiaohongshu/unfollow: 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/unfollow: 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/unfollow: user-id must be a Xiaohongshu user ID (e.g. 5d8f88dc0000000001005d3a) or full profile URL',\n        );\n    }\n    return userId;\n}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/unfollow.js#L25-L61","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n$ xiaohongshu unfollow 'https//www.xiaohongshu.com/user/profile/5d8f88dc0000000001005d3a'\n// after\n$ xiaohongshu unfollow 'https://www.xiaohongshu.com/user/profile/5d8f88dc0000000001005d3a'","handlingStrategy":"validation","validationCode":"const raw = String(arg ?? '').trim();\nif (/^https?:\\/\\//i.test(raw)) { try { new URL(raw); } catch { throw new Error('Not a valid URL: ' + raw); } }","typeGuard":"function looksLikeUrl(s) { return /^https?:\\/\\//i.test(String(s ?? '').trim()); }\nfunction isValidUrl(s) { try { new URL(String(s).trim()); return true; } catch { return false; } }","tryCatchPattern":"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; }","preventionTips":["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"],"tags":["argument-validation","url-parsing","cli"],"backgroundTag":"invalid-url-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}