{"record":{"id":"fbee4a441e95a628","repo":"jackwener/OpenCLI","slug":"label-must-be-an-exact-https-www-linkedin-com","errorCode":null,"errorMessage":"${label} must be an exact https://www.linkedin.com/in/<profile>/ URL","messagePattern":"(.+?) must be an exact https://www\\.linkedin\\.com/in/<profile>/ URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/connect.js","lineNumber":77,"sourceCode":"        url.hash = '';\n        url.search = '';\n        if (!url.pathname.endsWith('/')) url.pathname += '/';\n        return url.toString();\n    }\n    catch {\n        return '';\n    }\n}\n\nfunction requireStringArg(args, key, label = key) {\n    const value = normalizeWhitespace(args[key]);\n    if (!value) throw new ArgumentError(`${label} is required`);\n    return value;\n}\n\nfunction requireLinkedInProfileUrl(value, label) {\n    const url = canonicalizeLinkedInProfileUrl(value);\n    if (!url) throw new ArgumentError(`${label} must be an exact https://www.linkedin.com/in/<profile>/ URL`);\n    return url;\n}\n\nfunction clampNote(note) {\n    const value = normalizeWhitespace(note);\n    if (value.length > 300) throw new ArgumentError('--note must be 300 characters or fewer for LinkedIn connection requests');\n    return value;\n}\n\nfunction canonicalizeLinkedInInviteUrl(value) {\n    try {\n        const url = new URL(normalizeWhitespace(value), 'https://www.linkedin.com');\n        if (url.protocol !== 'https:' || url.username || url.password || url.port || !isLinkedInHost(url.hostname)) return '';\n        if (!/^\\/preload\\/custom-invite\\/?$/i.test(url.pathname)) return '';\n        url.hostname = 'www.linkedin.com';\n        url.hash = '';\n        if (!url.pathname.endsWith('/')) url.pathname += '/';\n        return url.toString();","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/connect.js#L59-L95","documentation":"requireLinkedInProfileUrl canonicalizes the supplied profile URL and rejects anything that is not an exact https://www.linkedin.com/in/<profile>/ URL. The library enforces strict canonical profile URLs so later navigation, matching, and safety checks operate on a predictable target.","triggerScenarios":"Passing --profile-url with: http:// instead of https://, a country-prefixed domain (e.g. linkedin.com or fr.linkedin.com), a trailing path (e.g. /in/jane/details/), missing trailing slash, a vanity name with invalid characters, or a non-profile LinkedIn URL (/company/, /posts/).","commonSituations":"Copying a profile URL from the mobile app (shares/posts links), from Google search results (tracking params, country TLD), or pasting a logged-out redirect URL instead of the canonical /in/<handle>/ form.","solutions":["Open the profile on desktop LinkedIn and copy the canonical URL: https://www.linkedin.com/in/<profile>/ with the trailing slash","Strip query strings, tracking params, and sub-paths from the URL","Replace http:// with https:// and remove any country subdomain or 'www.' variants if the canonicalizer rejects them","Verify the URL is a person profile (/in/), not a company (/company/) or post link"],"exampleFix":"// before\n--profile-url \"http://fr.linkedin.com/in/jane-doe?originalSubdomain=fr\"\n// after\n--profile-url \"https://www.linkedin.com/in/jane-doe/\"","handlingStrategy":"validation","validationCode":"const PROFILE_URL_RE = /^https:\\/\\/www\\.linkedin\\.com\\/in\\/[A-Za-z0-9\\-%_]+\\/$/;\nif (!PROFILE_URL_RE.test(profileUrl)) throw new Error(`--profile-url must be https://www.linkedin.com/in/<profile>/, got: ${profileUrl}`);","typeGuard":"function isCanonicalLinkedInProfileUrl(v) { try { const u = new URL(v); return u.protocol === 'https:' && u.hostname === 'www.linkedin.com' && /^\\/in\\/[^/]+\\/$/.test(u.pathname) && u.search === '' && u.hash === ''; } catch { return false; } }","tryCatchPattern":"try { await runConnect(args); } catch (e) { if (String(e.message).includes('must be an exact https://www.linkedin.com/in/')) { console.error('Normalize the URL to https://www.linkedin.com/in/<profile>/'); } else { throw e; } }","preventionTips":["Always copy profile URLs from desktop LinkedIn and keep the trailing slash","Strip query params, tracking params, and country subdomains before passing the URL","Reject non-/in/ URLs (company or post links) in your tooling","Add the canonical-URL regex to your input validation suite"],"tags":["cli","validation","url"],"backgroundTag":"invalid-url-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}