jackwener/OpenCLI · error · CommandExecutionError

LinkedIn company extraction ended on a non-LinkedIn page

Error message

LinkedIn company extraction ended on a non-LinkedIn page

What it means

normalizeCompanyOutputUrl requires the extraction's final URL to still be on an allowed linkedin.com host with https, no credentials, and no port. If the browser ended on any other domain — a redirect target, auth provider, or external site — this error is thrown because the result cannot represent a LinkedIn company page.

Source

Thrown at clis/linkedin/company.js:86

      founded: facts['founded'] || '',
      website: facts['website'] || '',
      specialties: facts['specialties'] || '',
      followers: followersMatch ? followersMatch[1].replace(/,/g, '') : '',
      about: about.slice(0, 2000),
    };
  })()`;
}

function normalizeCompanyOutputUrl(value, fallbackUrl) {
    const raw = normalizeWhitespace(value || fallbackUrl);
    let parsed;
    try {
        parsed = new URL(raw, `https://${LINKEDIN_DOMAIN}`);
    } catch {
        throw new CommandExecutionError('LinkedIn company extraction returned a malformed current URL');
    }
    if (parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.port || !LINKEDIN_COMPANY_HOSTS.has(parsed.hostname.toLowerCase())) {
        throw new CommandExecutionError('LinkedIn company extraction ended on a non-LinkedIn page');
    }
    const match = parsed.pathname.match(COMPANY_URL_RE);
    if (!match?.[1]) {
        throw new CommandExecutionError('LinkedIn company extraction ended outside a company page');
    }
    let slug;
    try {
        slug = decodeURIComponent(match[1]);
    } catch {
        throw new CommandExecutionError('LinkedIn company extraction returned a malformed company slug');
    }
    return `https://${LINKEDIN_DOMAIN}/company/${encodeURIComponent(slug)}/about/`;
}

function normalizeCompanyInfo(info, targetUrl) {
    if (!info || typeof info !== 'object' || Array.isArray(info)) {
        throw new CommandExecutionError('LinkedIn company extraction returned a malformed payload');
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure the scraping session is authenticated and cookies are fresh so no external redirect occurs
  2. Check what URL the run actually ended on (network log) and remove whatever caused the off-site redirect
  3. Use a direct https://www.linkedin.com/company/<slug>/ target without proxy wrappers
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const info = await company({ url: target });
} catch (err) {
  if (String(err.message).includes('non-LinkedIn page')) {
    // refresh session cookies and avoid proxies/SSO wrappers, then retry
    await refreshSession();
    return company({ url: target });
  }
  throw err;
}

Prevention

When it happens

Trigger: Company page redirected to an external auth/SSO domain, a bot-protection domain, or linkedin.com opened http with a port or userinfo; the extractor's location value points outside LINKEDIN_COMPANY_HOSTS after a redirect chain.

Common situations: Session expired and LinkedIn bounced to an external login flow; corporate proxy or SSO wrapping LinkedIn behind another host; anti-bot middleware redirecting to a challenge domain.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/7b6a4545657b73c5. Report an issue: GitHub.