{"record":{"id":"79049793ba94abed","repo":"jackwener/OpenCLI","slug":"linkedin-company-url-must-point-to-linkedin-com","errorCode":null,"errorMessage":"LinkedIn company URL must point to linkedin.com","messagePattern":"LinkedIn company URL must point to linkedin\\.com","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/company.js","lineNumber":30,"sourceCode":"const LINKEDIN_COMPANY_HOSTS = new Set(['linkedin.com', LINKEDIN_DOMAIN]);\n\n// Accept a bare universal name (`nvidia`), a `/company/<slug>` path, or a full\n// company URL, and return the canonical about-page URL.\nfunction normalizeCompanyUrl(value) {\n    const raw = normalizeWhitespace(value || '');\n    if (!raw) {\n        throw new CommandExecutionError('LinkedIn company requires a company universal name or URL');\n    }\n    let slug = raw;\n    if (/^https?:\\/\\//i.test(raw) || raw.startsWith('/company/')) {\n        let parsed;\n        try {\n            parsed = raw.startsWith('/') ? new URL(raw, `https://${LINKEDIN_DOMAIN}`) : new URL(raw);\n        } catch {\n            throw new CommandExecutionError(`LinkedIn company received a malformed URL: ${raw}`);\n        }\n        if (parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.port || !LINKEDIN_COMPANY_HOSTS.has(parsed.hostname.toLowerCase())) {\n            throw new CommandExecutionError('LinkedIn company URL must point to linkedin.com');\n        }\n        const m = parsed.pathname.match(COMPANY_URL_RE);\n        if (!m) throw new CommandExecutionError('LinkedIn company URL must look like /company/<name>');\n        try {\n            slug = decodeURIComponent(m[1]);\n        } catch {\n            throw new CommandExecutionError(`LinkedIn company URL has a malformed company slug: ${m[1]}`);\n        }\n    }\n    if (!SLUG_RE.test(slug)) {\n        throw new CommandExecutionError(`LinkedIn company name has unexpected characters: ${slug}`);\n    }\n    return `https://www.linkedin.com/company/${encodeURIComponent(slug)}/about/`;\n}\n\nfunction buildCompanyExtractionScript() {\n    return String.raw`(() => {\n    const clean = (s) => String(s || '').replace(/[  ]+/g, ' ').replace(/\\s+/g, ' ').trim();","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/company.js#L12-L48","documentation":"normalizeCompanyUrl validates that the user-supplied URL for a LinkedIn company page is an https URL on an allowed linkedin.com host with no credentials or explicit port. If any of these checks fail (wrong protocol, embedded userinfo, non-standard port, or hostname not in LINKEDIN_COMPANY_HOSTS), this error is thrown before any network request is made.","triggerScenarios":"Calling the company command with targetUrl set to a non-LinkedIn URL (e.g. a corporate site), an http:// LinkedIn URL, a URL containing user:pass@, an explicit port (:443/:8080), or a lookalike host like linkedin.company.com or www.linkedin.com.evil.io that is not in LINKEDIN_COMPANY_HOSTS.","commonSituations":"Config file or CLI flag holding the wrong URL (company homepage instead of the LinkedIn page); URL built by string concatenation adding a port; redirect/short-link resolving outside linkedin.com; pasting a URL with embedded credentials from a proxy tool.","solutions":["Use a canonical https LinkedIn company URL such as https://www.linkedin.com/company/<slug>/","Remove any userinfo (user:pass@) and explicit port from the URL","Ensure the hostname is exactly linkedin.com or www.linkedin.com (whatever LINKEDIN_COMPANY_HOSTS allows)","If normalizing user input, resolve short links first and pass only the final https://linkedin.com URL"],"exampleFix":"// before\nawait company({ url: 'http://linkedin.com:8080/company/acme' });\n// after\nawait company({ url: 'https://www.linkedin.com/company/acme/' });","handlingStrategy":"validation","validationCode":"function isValidCompanyUrl(u) { try { const p = new URL(u); return p.protocol === 'https:' && !p.username && !p.password && !p.port && /(^|\\.)linkedin\\.com$/.test(p.hostname) && /^\\/company\\/[^/]+/.test(p.pathname); } catch { return false; } }\nif (!isValidCompanyUrl(input)) throw new Error('Provide a canonical https://www.linkedin.com/company/<slug>/ URL');","typeGuard":"function isLinkedInCompanyUrl(u) { try { const p = new URL(u); return p.protocol === 'https:' && p.hostname === 'www.linkedin.com' && p.pathname.startsWith('/company/') && p.pathname.length > '/company/'.length; } catch { return false; } }","tryCatchPattern":"try {\n  const result = await company({ url: input });\n} catch (err) {\n  if (String(err.message).includes('must point to linkedin.com')) {\n    // fix or prompt for the URL before retrying\n  } else throw err;\n}","preventionTips":["Store canonical https://www.linkedin.com/company/<slug>/ URLs in config, never company homepages","Strip userinfo and ports from user-supplied URLs before passing them","Validate hostnames against linkedin.com exactly — do not accept subdomains of untrusted hosts"],"tags":["url-validation","linkedin","input-validation"],"backgroundTag":"invalid-url","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}