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

  1. Sign in to LinkedIn in the automated page before running the command (persist storageState/cookies between runs)
  2. Verify cookies exist: page.getCookies({ url: 'https://www.linkedin.com' }) should include JSESSIONID
  3. Refresh or re-create the saved session if it expired
  4. 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

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


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