jackwener/OpenCLI · error · ArgumentError

Could not resolve LinkedIn company filter

Error message

Could not resolve LinkedIn company filter: ${unresolved.join(', ')}

What it means

resolveCompanyIds tries to turn each `--company` value into a LinkedIn company filter ID. Numeric values are accepted directly; non-numeric names are resolved by typing them into the 'Add a company' input in the jobs search 'All filters' panel and reading the resulting suggestion inputs. When a name produces no matching suggestion, it is collected and this ArgumentError is thrown listing all unresolved names.

Solutions

  1. Find the company's numeric LinkedIn company ID (visible in its company page URL, e.g. /company/12345/) and pass the ID instead of a name — numeric values bypass resolution entirely.
  2. Re-run with the exact company name as it appears in LinkedIn's filter dropdown suggestions.
  3. Split the --company list and re-run to identify which specific names failed, then correct each one.
  4. Retry if the failure was likely a slow suggestion dropdown (timing); if it persists across runs, LinkedIn's DOM likely changed and the resolver needs updating.

Example fix

// before
opencli linkedin search "swe" --company "msft,Amazon Web Services"
// after (use numeric company IDs or exact suggestion names)
opencli linkedin search "swe" --company "1035,Amazon Web Services"
Defensive patterns

Strategy: validation

Validate before calling

// Prefer numeric LinkedIn company IDs — they skip DOM resolution entirely
const companies = (process.env.COMPANIES || '').split(',').map(s => s.trim()).filter(Boolean);
const nonNumeric = companies.filter(c => !/^\d+$/.test(c));
if (nonNumeric.length) {
  console.warn(`Names will be DOM-resolved (fragile): ${nonNumeric.join(', ')} — prefer numeric IDs from /company/<id>/ URLs`);
}

Type guard

const isCompanyId = (v) => /^\d+$/.test(String(v).trim());
const allCompanyIds = (list) => Array.isArray(list) && list.length > 0 && list.every(isCompanyId);

Try / catch

try {
  const rows = await run(['linkedin', 'search', query, '--company', companies.join(',')]);
} catch (e) {
  if (/Could not resolve LinkedIn company filter/.test(e.message)) {
    const bad = e.message.split(':')[1]?.split(',').map(s => s.trim()) ?? [];
    console.error(`Fix or replace these company names with numeric IDs: ${bad.join(', ')}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Running `opencli linkedin search "engineer" --company "Some Company"` where the name is not numeric and the in-page suggestion flow (click 'All filters', type name, wait 1200ms, read input[name="company-filter-value"] entries) yields no match — either exact or substring — for that name.

Common situations: Typo or incorrect casing in the company name; company name too generic or too long for LinkedIn's suggestion matching; LinkedIn UI changed so the 'Add a company' input or company-filter-value inputs no longer exist; page not fully loaded or A/B variant without the All filters panel; using an acronym ('MSFT') instead of the legal name ('Microsoft'); slow network so the 1200ms suggestion wait is insufficient.

Related errors


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

Appendix: source

Thrown at clis/linkedin/search.js:239

          inp.value = '';
          inp.dispatchEvent(new Event('input', { bubbles: true }));
          await sleep(100);
        }
      }
      results[name] = found || null;
    }
    return results;
  })()`);
    const unresolved = [];
    for (const name of names) {
        const id = resolved?.[name];
        if (id)
            ids.add(id);
        else
            unresolved.push(name);
    }
    if (unresolved.length) {
        throw new ArgumentError(`Could not resolve LinkedIn company filter: ${unresolved.join(', ')}`);
    }
    return [...ids];
}
// ── Voyager API fetch (runs inside page context for cookie access) ────
async function fetchJobCards(page, input) {
    const MAX_BATCH = 25;
    const allJobs = [];
    let offset = input.start;
    // Read JSESSIONID directly from the cookie store via CDP — zero page.evaluate round-trip
    const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });
    const jsession = cookies.find((c) => c.name === 'JSESSIONID')?.value;
    if (!jsession) {
        throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.');
    }
    const csrf = jsession.replace(/^"|"$/g, '');
    while (allJobs.length < input.limit) {
        const count = Math.min(MAX_BATCH, input.limit - allJobs.length);
        const apiPath = buildVoyagerUrl(input, offset, count);

View on GitHub (pinned to 49907e53dc)