jackwener/OpenCLI · error · AuthRequiredError
LinkedIn JSESSIONID cookie not found. Please sign in to Link
Error message
LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn.
What it means
Thrown in clis/linkedin/salesnav-search.js:147 after navigating to Sales Navigator home and reading cookies for https://www.linkedin.com: no cookie named JSESSIONID was present. JSESSIONID is required to derive the csrf-token header for LinkedIn REST API calls. Its absence means the browser is not signed in to LinkedIn (or the session cookie was not scoped to the www domain), so the search cannot authenticate. The error is raised as AuthRequiredError, signaling the user must log in.
Source
Thrown at clis/linkedin/salesnav-search.js:147
strategy: Strategy.UI,
browser: true,
args: [
{ name: 'keywords', type: 'string', required: true, positional: true, help: 'People search keywords, e.g. "quality manager food manufacturing"' },
{ name: 'limit', type: 'number', default: 25, help: 'Maximum leads to return (1-500, fetched 25 per request)' },
],
columns: ['rank', 'name', 'title', 'company', 'location', 'degree', 'profile_url', 'lead_url', 'recipient_urn'],
func: async (page, args) => {
if (!page) throw new CommandExecutionError('Browser session required for linkedin salesnav-search');
const keywords = requireStringArg(args, 'keywords', '--keywords');
const limit = parseLimit(args.limit);
await page.goto(SALES_HOME);
await page.wait(6);
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.');
}
const csrf = jsession.replace(/^\"|\"$/g, '');
const leads = [];
const seen = new Set();
for (let start = 0; leads.length < limit && start < 2000; start += PAGE_SIZE) {
const result = unwrapEvaluateResult(await page.evaluate(fetchLeadSearchScript(leadSearchUrl(keywords, start), csrf)));
const json = requireLeadSearchResult(result);
const pageLeads = parseLeads(json);
if (pageLeads.length === 0) break;
for (const lead of pageLeads) {
const key = lead.profile_url || lead.name.toLowerCase();
if (seen.has(key)) continue;
seen.add(key);
leads.push(lead);
}
await page.wait(1);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Sign in to LinkedIn in the automation browser (run the platform's login flow) and retry the command.
- Verify the session by loading https://www.linkedin.com/feed/ and confirming you are not redirected to the login page.
- Check cookies manually for a www.linkedin.com JSESSIONID (document.cookie or devtools) to rule out domain-scoping mismatches.
- If the profile persists cookies but the session keeps dropping, re-authenticate and avoid sharing the profile across concurrent automation runs.
Example fix
// before (assume cookie exists)
const csrf = jsession.replace(/^"|"$/g, '');
// after (check login state before reading cookies)
await page.goto('https://www.linkedin.com/feed/');
if (/login/.test(page.url())) { await interactiveLogin(page); }
const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });
const jsession = cookies.find((c) => c.name === 'JSESSIONID')?.value;
if (!jsession) throw new AuthRequiredError('www.linkedin.com', 'sign in first'); Defensive patterns
Strategy: validation
Validate before calling
// Verify login state before the API flow:
await page.goto('https://www.linkedin.com/feed/');
if (/\/login|checkpoint/.test(page.url())) {
throw new AuthRequiredError('www.linkedin.com', 'Sign in to LinkedIn before running salesnav-search');
}
const hasJsession = (await page.getCookies({ url: 'https://www.linkedin.com' }))
.some((c) => c.name === 'JSESSIONID' && c.value);
if (!hasJsession) throw new AuthRequiredError('www.linkedin.com', 'JSESSIONID missing; log in again'); Type guard
function hasLinkedInSession(cookies) {
return Array.isArray(cookies) && cookies.some(
(c) => c.name === 'JSESSIONID' && typeof c.value === 'string' && c.value.length > 0
);
} Try / catch
try {
const leads = await run('linkedin salesnav-search', [keywords]);
} catch (err) {
if (err instanceof AuthRequiredError) {
await interactiveLogin(page); // open login flow, wait for user/2FA
return run('linkedin salesnav-search', [keywords]);
}
throw err;
} Prevention
- Use a persistent browser profile that keeps the LinkedIn session across runs, and re-login proactively when sessions expire.
- Check for JSESSIONID (or a logged-in marker) at pipeline start and authenticate before batch operations.
- Avoid sharing one automation profile across concurrent jobs, which can trigger LinkedIn security logouts.
When it happens
Trigger: page.getCookies() returns no JSESSIONID because the browser profile is logged out; cookies are scoped to a different domain/subdomain than https://www.linkedin.com; navigating to /sales/ redirected to a login page; cookie expiry or a LinkedIn logout wiping the session.
Common situations: Fresh automation browser profile with no saved LinkedIn login; session expired after LinkedIn's security logout; running from a region/IP that forces re-authentication; using a profile where cookies are stored under linkedin.com without www and the lookup URL filter misses them.
Related errors
- ${context} requires an active signed-in LinkedIn browser ses
- LinkedIn JSESSIONID cookie not found. Please sign in to Link
- LinkedIn messaging API authentication failed:
- LinkedIn JSESSIONID cookie not found. Please sign in to Link
- LinkedIn JSESSIONID cookie not found. Please sign in to Link
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7bed2e0e78c5f147.
Report an issue: GitHub.