{"record":{"id":"51682c4b13b8693b","repo":"jackwener/OpenCLI","slug":"linkedin-company-extraction-returned-a-malformed-p","errorCode":null,"errorMessage":"LinkedIn company extraction returned a malformed payload","messagePattern":"LinkedIn company extraction returned a malformed payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/company.js","lineNumber":103,"sourceCode":"    if (parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.port || !LINKEDIN_COMPANY_HOSTS.has(parsed.hostname.toLowerCase())) {\n        throw new CommandExecutionError('LinkedIn company extraction ended on a non-LinkedIn page');\n    }\n    const match = parsed.pathname.match(COMPANY_URL_RE);\n    if (!match?.[1]) {\n        throw new CommandExecutionError('LinkedIn company extraction ended outside a company page');\n    }\n    let slug;\n    try {\n        slug = decodeURIComponent(match[1]);\n    } catch {\n        throw new CommandExecutionError('LinkedIn company extraction returned a malformed company slug');\n    }\n    return `https://${LINKEDIN_DOMAIN}/company/${encodeURIComponent(slug)}/about/`;\n}\n\nfunction normalizeCompanyInfo(info, targetUrl) {\n    if (!info || typeof info !== 'object' || Array.isArray(info)) {\n        throw new CommandExecutionError('LinkedIn company extraction returned a malformed payload');\n    }\n    if (!info.name) {\n        throw new CommandExecutionError('LinkedIn company page rendered but no company name was found (layout drift or company not found)');\n    }\n    let followers = 0;\n    if (info.followers) {\n        followers = Number(info.followers);\n        if (!Number.isFinite(followers)) {\n            throw new CommandExecutionError('LinkedIn company extraction returned a malformed followers count');\n        }\n    }\n    return {\n        name: String(info.name),\n        industry: String(info.industry || ''),\n        size: String(info.size || ''),\n        headquarters: String(info.headquarters || ''),\n        founded: String(info.founded || ''),\n        website: String(info.website || ''),","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/company.js#L85-L121","documentation":"normalizeCompanyInfo expects the extraction payload to be a plain object. If the in-page script returned null, undefined, an array, or any non-object, the library throws because it cannot read name/followers fields from it. This guards against silently producing an empty result when extraction failed structurally.","triggerScenarios":"Page script returned null/undefined because its querySelectors matched nothing and it bailed out; serialization between the browser context and Node mangled the result into a string; extraction ran on a page whose layout changed so the payload builder returned an array or nothing.","commonSituations":"LinkedIn markup update (layout drift) breaking the extractor's selectors; scraping a captcha/login interstitial where no company data exists; version mismatch between the CLI and the injected extraction script.","solutions":["Update the library to a version whose extraction script matches the current LinkedIn layout","Confirm the session reached a real company page (not a login or captcha wall) before extraction","Retry the command; transient rendering failures can yield empty payloads","Inspect the raw extractor output by logging before normalization to see what shape was returned"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isExtractionPayload(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }","tryCatchPattern":"try {\n  const info = await company({ url: target });\n} catch (err) {\n  if (String(err.message).includes('malformed payload')) {\n    // extraction returned non-object: check for captcha/login wall, retry once\n    return withRetry(() => company({ url: target }), 1);\n  }\n  throw err;\n}","preventionTips":["Update the library when LinkedIn's DOM changes (layout drift)","Detect login/captcha interstitials before running extraction","Log the raw extractor output in debug mode to see what shape was returned"],"tags":["scraping","linkedin","layout-drift"],"backgroundTag":"scrape-extraction-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}