jackwener/OpenCLI · critical · 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
This AuthRequiredError is thrown by getCsrf when the browser cookie jar for www.linkedin.com contains no JSESSIONID cookie. The JSESSIONID value doubles as the CSRF token for Sales Navigator API calls, so without it the session is not signed in and authenticated requests cannot be built.
Source
Thrown at clis/linkedin/salesnav-inbox.js:121
accept: 'application/json',
},
});
const text = await res.text();
let json = null;
try { json = text ? JSON.parse(text) : null; } catch (_) { json = null; }
if (res.status === 401 || res.status === 403) return { authRequired: true, status: res.status, text };
if (!res.ok) return { error: 'HTTP ' + res.status, status: res.status, text, json };
return { status: res.status, json };
} catch (e) {
return { error: 'fetch failed: ' + ((e && e.message) || String(e)) };
}
})()`;
}
export async function getCsrf(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(LINKEDIN_DOMAIN, 'LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn.');
return jsession.replace(/^\"|\"$/g, '');
}
export async function fetchSalesnavJson(page, csrf, url, label) {
const result = unwrapEvaluateResult(await page.evaluate(fetchJsonScript(url, csrf)));
if (result?.authRequired) throw new AuthRequiredError(LINKEDIN_DOMAIN, `${label} authentication failed (HTTP ${result.status || 'auth_required'}).`);
if (result?.error || !result?.json) throw new CommandExecutionError(`${label} returned an unexpected response`, `${result?.error || 'no_json'}\n${normalizeWhitespace(result?.text || '').slice(0, 500)}`);
return result.json;
}
export async function fetchInboxRows(page, { limit = DEFAULT_LIMIT, maxPages = 30 } = {}) {
const csrf = await getCsrf(page);
const rows = [];
const seen = new Set();
let pageStartsAt = '';
let pagesFetched = 0;
let hasMorePages = false;
while (rows.length < limit && pagesFetched < maxPages) {View on GitHub (pinned to 49907e53dc)
Solutions
- Sign in to LinkedIn in the automated page before running the command (persist storageState/cookies between runs)
- Verify cookies exist: page.getCookies({ url: 'https://www.linkedin.com' }) should include JSESSIONID
- Refresh or re-create the saved session if it expired
- Ensure the browser context is not incognito/ephemeral without loading saved cookies
Example fix
// before const page = await browser.newPage(); // no cookies await fetchInboxRows(page); // after const page = await browser.newPage(); await page.setCookie(...savedLinkedInCookies); // or restore storageState await fetchInboxRows(page);
Defensive patterns
Strategy: try-catch
Validate before calling
const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });
if (!cookies.some((c) => c.name === 'JSESSIONID')) {
throw new Error('Not signed in: run LinkedIn login before scraping');
} Type guard
function isSignedIn(cookies) {
return Array.isArray(cookies) && cookies.some((c) => c.name === 'JSESSIONID' && !!c.value);
} Try / catch
try {
const rows = await fetchInboxRows(page);
} catch (e) {
if (String(e.message).includes('JSESSIONID')) {
await interactiveLogin(page); // or restore saved cookies
return fetchInboxRows(page);
}
throw e;
} Prevention
- Persist LinkedIn cookies/storageState between runs
- Run an explicit login step before scraping commands
- Detect expired sessions early with a lightweight auth check
- Avoid ephemeral incognito contexts without loaded cookies
When it happens
Trigger: Calling fetchInboxRows (which calls getCsrf) while the Puppeteer/Playwright page is not signed in to LinkedIn, the session expired so LinkedIn dropped JSESSIONID, or cookies were cleared / a fresh profile context was used.
Common situations: Running the scraper with a fresh browser profile that never logged in; LinkedIn invalidated the session (password change, security logout); cookie expiry after long runs; using a context that blocks or partitions cookies.
Related errors
- 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
- ${context} requires an active signed-in LinkedIn browser ses
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a1b52b9d8c69eeb9.
Report an issue: GitHub.