{"record":{"id":"7cb532b2482d211a","repo":"jackwener/OpenCLI","slug":"linkedin-li-at-cookie-missing","errorCode":null,"errorMessage":"LinkedIn li_at cookie missing","messagePattern":"LinkedIn li_at cookie missing","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/auth.js","lineNumber":11,"sourceCode":"import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';\nimport { registerSiteAuthCommands } from '../_shared/site-auth.js';\n\nasync function hasLinkedinSessionCookie(page) {\n  const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });\n  return cookies.some(c => c.name === 'li_at' && c.value);\n}\n\nasync function verifyLinkedinIdentity(page) {\n  if (!await hasLinkedinSessionCookie(page)) {\n    throw new AuthRequiredError('linkedin.com', 'LinkedIn li_at cookie missing');\n  }\n  await page.goto('https://www.linkedin.com/feed/');\n  await page.wait(2);\n  const result = await page.evaluate(`(async () => {\n    try {\n      const jsessionRaw = (document.cookie.split('; ').find(c => c.startsWith('JSESSIONID=')) || '').split('=')[1] || '';\n      const csrf = jsessionRaw.replace(/^\"|\"$/g, '');\n      if (!csrf) return { kind: 'auth', detail: 'LinkedIn JSESSIONID missing — csrf token unavailable' };\n      const res = await fetch('/voyager/api/me', { credentials: 'include', headers: { 'csrf-token': csrf, 'Accept': 'application/json' } });\n      if (res.status === 401 || res.status === 403) {\n        return { kind: 'auth', detail: 'LinkedIn /voyager/api/me HTTP ' + res.status };\n      }\n      if (!res.ok) return { kind: 'http', httpStatus: res.status };\n      const d = await res.json();\n      const mini = d && d.miniProfile;\n      if (!mini || !mini.publicIdentifier) {\n        return { kind: 'auth', detail: 'LinkedIn /voyager/api/me 200 but miniProfile missing' };\n      }","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/auth.js#L1-L29","documentation":"verifyLinkedinIdentity first checks the browser context for a non-empty li_at session cookie; if absent it throws AuthRequiredError('linkedin.com', ...). li_at is LinkedIn's persistent login cookie — without it every authenticated Voyager API call would 401, so the library fails fast and tells the caller to log in.","triggerScenarios":"Calling any linkedin command without a prior successful login: the browser profile has no cookies, cookies expired/were cleared, or getCookies({url:'https://www.linkedin.com'}) returns no li_at entry.","commonSituations":"Fresh automation environment with no logged-in profile; LinkedIn invalidated sessions (users are logged out periodically); clearing browser data between runs; wrong profile directory configured for the headless browser.","solutions":["Run the site's login flow (e.g. `cli auth linkedin`) and complete LinkedIn login to mint an li_at cookie.","Point the automation at the browser profile where you are already logged into LinkedIn.","Persist the profile directory between runs so the cookie survives restarts.","Re-login whenever LinkedIn expires the session; treat this error as the trigger for re-auth."],"exampleFix":"// before\nawait run('linkedin company nvidia'); // AuthRequiredError: LinkedIn li_at cookie missing\n// after\nawait run('auth linkedin');           // interactive login, stores li_at\nawait run('linkedin company nvidia');","handlingStrategy":"validation","validationCode":"const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });\nif (!cookies.some(c => c.name === 'li_at' && c.value)) {\n  await run('auth linkedin'); // login before scraping\n}","typeGuard":"function hasLinkedInSession(cookies) {\n  return Array.isArray(cookies) && cookies.some(c => c.name === 'li_at' && !!c.value);\n}","tryCatchPattern":"try {\n  await run('linkedin company nvidia');\n} catch (e) {\n  if (e instanceof AuthRequiredError || /li_at cookie missing/.test(e.message)) {\n    await run('auth linkedin');\n    return run('linkedin company nvidia');\n  }\n  throw e;\n}","preventionTips":["Persist the browser profile directory between runs.","Run the auth flow as a pre-flight step in automation scripts.","Monitor cookie expiry and re-login proactively.","Catch AuthRequiredError and trigger re-auth automatically."],"tags":["auth","session","cookie"],"backgroundTag":"missing-session-cookie","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}