jackwener/OpenCLI · error · CommandExecutionError

LinkedIn company extraction ended outside a company page

Error message

LinkedIn company extraction ended outside a company page

What it means

Even when the final URL is on linkedin.com, the path must still match COMPANY_URL_RE with a captured slug. If the browser ended outside a /company/<name> path (feed, login, search results, redirected company page), this error is thrown because no company slug can be extracted.

Source

Thrown at clis/linkedin/company.js:90

      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');
    }
    if (!info.name) {
        throw new CommandExecutionError('LinkedIn company page rendered but no company name was found (layout drift or company not found)');
    }
    let followers = 0;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the company slug exists by opening the URL in a browser first
  2. Wait for the SPA to finish navigating before running extraction (or retry the command)
  3. Re-authenticate the scraping session to avoid authwall redirects
  4. Use the canonical /company/<slug>/about/ URL as targetUrl
Defensive patterns

Strategy: retry

Validate before calling

function isCompanyAboutUrl(u) { try { return /\/company\/[^/]+/.test(new URL(u).pathname); } catch { return false; } }
// pre-check the target before invoking
if (!isCompanyAboutUrl(target)) throw new Error('Target must be a /company/<slug> URL');

Try / catch

try {
  const info = await company({ url: target });
} catch (err) {
  if (String(err.message).includes('outside a company page')) {
    await wait(2000); // allow SPA navigation to settle
    return company({ url: target });
  }
  throw err;
}

Prevention

When it happens

Trigger: Company page redirected to the LinkedIn feed, authwall, or homepage because the session was unauthenticated or the company does not exist; extraction ran while the SPA was still navigating so location.pathname was not yet /company/...; slug-less URL like /company/ (empty name).

Common situations: Deleted/renamed company slug leading LinkedIn to bounce to a search or feed page; rate-limit or authwall interstitial; scraping too early before client-side routing settled.

Related errors


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