jackwener/OpenCLI · error · CommandExecutionError
LinkedIn redirected away from the search page (${result.erro
Error message
LinkedIn redirected away from the search page (${result.error}). Likely Commercial Use Limit reached - the limit resets on the 1st of next month. What it means
If the extraction script reports result.error but the page does not look like the auth wall, the library concludes LinkedIn redirected away from the people-search results — which in practice means the account's Commercial Use Limit (CUL) for search was reached or the account is otherwise gated. It throws CommandExecutionError advising the user that CUL resets on the 1st of the next month.
Source
Thrown at clis/linkedin/people-search.js:228
}
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.');
}
let result;
try {
result = unwrapEvaluateResult(await page.evaluate(extractionScript()));
} catch (error) {
throw new CommandExecutionError(`LinkedIn people search extraction failed: ${error?.message || error}`);
}
if (result?.error) {
if (looksLinkedInAuthWall(`${result.url || ''} ${result.error || ''}`)) {
throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn people search requires an active signed-in browser session.');
}
// If LinkedIn redirected away from the search page that
// usually means CUL was reached or the account is gated.
throw new CommandExecutionError(`LinkedIn redirected away from the search page (${result.error}). Likely Commercial Use Limit reached - the limit resets on the 1st of next month.`);
}
if (!result || typeof result !== 'object') {
throw new CommandExecutionError('LinkedIn people search returned malformed extraction payload');
}
const candidateCount = parseNonNegativeCount(result.candidate_count, 'candidate_count');
parseNonNegativeCount(result.person_entries_count, 'person_entries_count');
const resolvedCount = parseNonNegativeCount(result.resolved_count, 'resolved_count');
const rows = normalizePeopleRows(result.rows);
if (rows.length === 0 && (candidateCount > 0 || resolvedCount > 0)) {
throw new CommandExecutionError('LinkedIn people search found profile candidates but could not parse stable result rows');
}
if (rows.length === 0) {
throw new EmptyResultError(`No people found on the rendered page for "${keywords}". The search may have returned zero results, or the DOM markup may have changed.`);
}
return rows.slice(0, limit).map((p, i) => ({ rank: i + 1, ...p }));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Wait until the 1st of next month for CUL to reset, then retry
- Reduce search volume / spread queries across the month (respect the --limit flag)
- Use an account tier that includes commercial search (Premium/Sales Navigator/Recruiter)
- Check the account in a browser: if linkedin.com shows an upgrade/limit banner, that confirms CUL
- Distinguish from auth issues — if a login wall appears instead, fix auth first (see 2345/2347)
Example fix
// before: hard loop burning remaining CUL
for (const kw of keywords) await cli('linkedin people-search', { keywords: kw });
// after: stop on CUL error
try { await cli('linkedin people-search', { keywords: kw }); }
catch (e) { if (String(e.message).includes('Commercial Use Limit')) break; throw e; } Defensive patterns
Strategy: fallback
Validate before calling
// track monthly search usage yourself and stop before LinkedIn's CUL
const used = await getMonthlySearchCount();
if (used >= CUL_BUDGET) throw new Error('Local CUL budget reached; skip searches until next month'); Type guard
null
Try / catch
try { await cli('linkedin people-search', args); }
catch (e) { if (/Commercial Use Limit/.test(e.message)) { return fallbackDataSource(args); } throw e; } Prevention
- Budget searches monthly and stop before hitting CUL (resets on the 1st)
- Use a commercial-tier account (Premium/Sales Navigator) for heavy search needs
- Cache/dedupe search results to reduce query count
- Fall back to non-search LinkedIn APIs or stored data when gated
- Distinguish CUL redirects from auth walls so the right remedy is applied
When it happens
Trigger: result.error set, looksLinkedInAuthWall returns false, and the final URL is not the search page — LinkedIn bounced the search to a generic feed/upgrade page after the monthly CUL quota of searches was exhausted or the account lacks commercial search features.
Common situations: Free/basic accounts after exhausting monthly people-search credits; accounts without Sales Navigator/Recruiter commercial features searching too often; end-of-month quota exhaustion; LinkedIn A/B-gating the account.
Related errors
- ${batch.error}
- LinkedIn warning/restriction state visible on sent invitatio
- API_ERROR
- API_ERROR
- archive snapshots failed: HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/88fbfc7fcdc827e7.
Report an issue: GitHub.