{"record":{"id":"4e0cbce2824a5e4c","repo":"jackwener/OpenCLI","slug":"linkedin-jsessionid-cookie-not-found-please-sign-4e0cbc","errorCode":null,"errorMessage":"LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.","messagePattern":"LinkedIn JSESSIONID cookie not found\\. Please sign in to LinkedIn in the browser\\.","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/search.js","lineNumber":252,"sourceCode":"            ids.add(id);\n        else\n            unresolved.push(name);\n    }\n    if (unresolved.length) {\n        throw new ArgumentError(`Could not resolve LinkedIn company filter: ${unresolved.join(', ')}`);\n    }\n    return [...ids];\n}\n// ── Voyager API fetch (runs inside page context for cookie access) ────\nasync function fetchJobCards(page, input) {\n    const MAX_BATCH = 25;\n    const allJobs = [];\n    let offset = input.start;\n    // Read JSESSIONID directly from the cookie store via CDP — zero page.evaluate round-trip\n    const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });\n    const jsession = cookies.find((c) => c.name === 'JSESSIONID')?.value;\n    if (!jsession) {\n        throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.');\n    }\n    const csrf = jsession.replace(/^\"|\"$/g, '');\n    while (allJobs.length < input.limit) {\n        const count = Math.min(MAX_BATCH, input.limit - allJobs.length);\n        const apiPath = buildVoyagerUrl(input, offset, count);\n        const batch = await page.evaluate(`(async () => {\n      const res = await fetch(${JSON.stringify(apiPath)}, {\n        credentials: 'include',\n        headers: { 'csrf-token': ${JSON.stringify(csrf)}, 'x-restli-protocol-version': '2.0.0' },\n      });\n      if (res.status === 401 || res.status === 403) {\n        const text = await res.text();\n        return {\n          authRequired: true,\n          error: 'LinkedIn API authentication failed: HTTP ' + res.status + ' ' + text.slice(0, 200)\n        };\n      }\n      if (!res.ok) {","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/search.js#L234-L270","documentation":"fetchJobCards reads the browser's cookies for linkedin.com (via CDP getCookies) to obtain JSESSIONID, which doubles as the CSRF token for LinkedIn's internal Voyager API. If no JSESSIONID cookie exists in the browser profile, the command cannot make authenticated API calls and throws this AuthRequiredError telling the user to sign in to LinkedIn in the browser.","triggerScenarios":"Running `opencli linkedin search <query>` with a browser profile that has no linkedin.com session: never logged in, logged out, cookies cleared, or the wrong/empty browser profile was launched (Strategy.COOKIE mode).","commonSituations":"Fresh automation profile with no manual login; cookies expired or LinkedIn invalidated the session; running in CI/headless where no one signed in; cookie clearing tools or incognito mode wiping JSESSIONID between runs; multiple browser profiles and the CLI picked one without LinkedIn cookies.","solutions":["Open the browser profile used by the CLI, navigate to linkedin.com, and sign in manually, then re-run the command.","Verify the command is using the intended browser profile/directory (one that actually contains the LinkedIn session).","Check that cookies are not being cleared between runs (avoid incognito or aggressive cleanup); confirm JSESSIONID exists via the browser devtools cookie panel.","If LinkedIn is repeatedly dropping the session, reduce request frequency and keep the profile persistent so cookies survive."],"exampleFix":"// before (headless run with fresh profile — no session)\nawait cli.run(['linkedin', 'search', 'nodejs']);\n// after — sign in once in the persistent profile first\nawait page.goto('https://www.linkedin.com/login');\n// ...complete manual login, then:\nawait cli.run(['linkedin', 'search', 'nodejs']);","handlingStrategy":"try-catch","validationCode":"// Check the automation browser actually has a LinkedIn session before running\nconst cookies = await context.cookies('https://www.linkedin.com');\nconst hasSession = cookies.some(c => c.name === 'JSESSIONID' && c.value);\nif (!hasSession) {\n  console.error('Sign in to LinkedIn in the automation browser profile first.');\n  process.exit(2);\n}","typeGuard":"const hasLinkedInSession = (cookies) =>\n  Array.isArray(cookies) && cookies.some(c => c?.name === 'JSESSIONID' && typeof c.value === 'string' && c.value.length > 0);","tryCatchPattern":"try {\n  const jobs = await run(['linkedin', 'search', 'nodejs']);\n} catch (e) {\n  if (/JSESSIONID cookie not found/.test(e.message) || e.name === 'AuthRequiredError') {\n    console.error('Open the browser profile, sign in to linkedin.com, then retry.');\n    process.exit(2); // auth-class failure, not a bug\n  }\n  throw e;\n}","preventionTips":["Use a persistent browser profile and sign in to LinkedIn once manually before automating.","Never run LinkedIn commands from incognito or cookie-clearing profiles.","Re-check session validity periodically; long-lived sessions can still be invalidated server-side.","Keep automation frequency low so LinkedIn does not proactively expire the session."],"tags":["linkedin","authentication","csrf","cookies","browser-session"],"backgroundTag":"missing-session-cookie","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}