{"record":{"id":"0c859aa35ac0db7c","repo":"jackwener/OpenCLI","slug":"waiting-for-linkedin-li-at-cookie","errorCode":null,"errorMessage":"Waiting for LinkedIn li_at cookie","messagePattern":"Waiting for LinkedIn li_at cookie","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"info","filePath":"clis/linkedin/auth.js","lineNumber":58,"sourceCode":"    }\n  })()`);\n  if (result?.kind === 'auth') throw new AuthRequiredError('linkedin.com', result.detail);\n  if (result?.kind === 'http') throw new CommandExecutionError(`HTTP ${result.httpStatus} from /voyager/api/me`);\n  if (result?.kind === 'exception') throw new CommandExecutionError(`LinkedIn whoami failed: ${result.detail}`);\n  if (!result?.ok) throw new CommandExecutionError(`Unexpected LinkedIn probe: ${JSON.stringify(result)}`);\n  return { public_id: result.public_id, plain_id: result.plain_id, name: result.name };\n}\n\nregisterSiteAuthCommands({\n  site: 'linkedin',\n  domain: 'www.linkedin.com',\n  loginUrl: 'https://www.linkedin.com/login',\n  columns: ['public_id', 'plain_id', 'name'],\n  quickCheck: hasLinkedinSessionCookie,\n  verify: verifyLinkedinIdentity,\n  poll: async (page) => {\n    if (!await hasLinkedinSessionCookie(page)) {\n      throw new AuthRequiredError('linkedin.com', 'Waiting for LinkedIn li_at cookie');\n    }\n    return verifyLinkedinIdentity(page);\n  },\n});\n","sourceCodeStart":40,"sourceCodeEnd":63,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/auth.js#L40-L63","documentation":"The login-flow poll callback checks hasLinkedinSessionCookie on every poll tick; until the li_at cookie appears it throws AuthRequiredError('linkedin.com', 'Waiting for LinkedIn li_at cookie') to signal 'not finished yet'. The auth harness treats these polls as retryable and keeps waiting for the user to complete login.","triggerScenarios":"During interactive login the poll runs before the user has submitted credentials, or login failed/stalled so li_at never gets set — each poll raises this until the cookie exists.","commonSituations":"User simply hasn't finished typing credentials yet (benign, expected); login attempt failed (wrong password, blocked by 2FA/captcha); login page stuck due to headless-browser detection.","solutions":["Complete the LinkedIn login in the automated browser window — this error clears once li_at is set.","If login was rejected, retry with correct credentials and complete any 2FA/captcha.","Increase poll timeout if the human user needs more time.","If it persists after successful login, check that cookies are being persisted to the right profile (hasLinkedinSessionCookie quickCheck)."],"exampleFix":"// before\nawait auth('linkedin', { timeout: 5000 }); // keeps throwing 'Waiting for LinkedIn li_at cookie'\n// after\nawait auth('linkedin', { timeout: 300000 }); // give the user time to log in","handlingStrategy":"retry","validationCode":"const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });\nconst ready = cookies.some(c => c.name === 'li_at' && c.value); // poll until ready","typeGuard":"null","tryCatchPattern":"// during login flow, treat this as 'not ready yet'\ntry {\n  await pollAuth();\n} catch (e) {\n  if (/Waiting for LinkedIn li_at cookie/.test(e.message)) {\n    return scheduleNextPoll(); // keep waiting for user login\n  }\n  throw e;\n}","preventionTips":["Set a generous login timeout for interactive flows.","Have the user complete 2FA/captcha promptly.","Verify the login attempt succeeded if polls keep failing after submission."],"tags":["auth","login-flow","polling"],"backgroundTag":"auth-flow-pending","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}