{"record":{"id":"65848afefbbf1667","repo":"jackwener/OpenCLI","slug":"linkedin-company-url-has-a-malformed-company-slug","errorCode":null,"errorMessage":"LinkedIn company URL has a malformed company slug: ${m[1]}","messagePattern":"LinkedIn company URL has a malformed company slug: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/company.js","lineNumber":37,"sourceCode":"        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();\n    const facts = {};\n    for (const dt of Array.from(document.querySelectorAll('dt'))) {\n      const key = clean(dt.innerText || dt.textContent || '').toLowerCase().replace(/:$/, '');\n      const dd = dt.nextElementSibling;\n      const val = dd ? clean(dd.innerText || dd.textContent || '') : '';\n      if (key && val && !(key in facts)) facts[key] = val;\n    }","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/company.js#L19-L55","documentation":"The company slug captured from the URL path is percent-encoded; decodeURIComponent fails when it contains invalid escape sequences (e.g. a stray % not followed by two hex digits). The library treats such a slug as unusable and throws instead of passing a corrupt name downstream.","triggerScenarios":"targetUrl path containing a malformed percent-escape such as /company/acme%zz or /company/100% done; a slug produced by manual or broken encoding that inserted a lone % character.","commonSituations":"Double-encoding or hand-truncating a URL so '%25' becomes '%'; copy/paste from a document that mangled the escape; templating code that inserted a raw '%' placeholder into the URL.","solutions":["Fix the URL so percent escapes are valid (e.g. /company/acme%2520corp for a literal %)","Encode reserved characters properly: encodeURIComponent on dynamic slug parts before interpolating","Remove the stray % or truncate trailing punctuation from the slug"],"exampleFix":"// before\nconst url = `https://www.linkedin.com/company/${raw}%`;\n// after\nconst url = `https://www.linkedin.com/company/${encodeURIComponent(raw)}/`;","handlingStrategy":"validation","validationCode":"function hasValidEncoding(u) { try { const p = new URL(u); return p.pathname.split('/').every(seg => { try { decodeURIComponent(seg); return true; } catch { return false; } }); } catch { return false; } }\nif (!hasValidEncoding(input)) throw new Error('URL contains invalid percent-encodings');","typeGuard":"function isDecodableSlug(s) { try { decodeURIComponent(s); return true; } catch { return false; } }","tryCatchPattern":"try {\n  const result = await company({ url: input });\n} catch (err) {\n  if (String(err.message).includes('malformed company slug')) {\n    // rebuild the URL with encodeURIComponent on the dynamic slug\n  } else throw err;\n}","preventionTips":["Always build URLs with encodeURIComponent on dynamic slug parts","Never hand-edit percent escapes; regenerate the URL from the raw slug","Validate user-pasted URLs with decodeURIComponent before passing them"],"tags":["url-validation","encoding","linkedin"],"backgroundTag":"invalid-url-encoding","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}