{"record":{"id":"c6d1320a7f395ed3","repo":"jackwener/OpenCLI","slug":"linkedin-thread-snapshot-requires-an-active-signed","errorCode":null,"errorMessage":"LinkedIn thread-snapshot requires an active signed-in LinkedIn browser session.","messagePattern":"LinkedIn thread-snapshot requires an active signed-in LinkedIn browser session\\.","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":336,"sourceCode":"    await page.wait(10);\n\n    let discovery = unwrapEvaluateResult(await page.evaluate(buildThreadApiDiscoveryScript(maxScrolls)));\n    if (discovery && Array.isArray(discovery.apiUrls) && discovery.apiUrls.length === 0) {\n      const firstDiscovery = discovery;\n      await page.wait(4);\n      const retried = unwrapEvaluateResult(await page.evaluate(buildThreadApiDiscoveryScript(0)));\n      if (retried && typeof retried === 'object' && !Array.isArray(retried)) {\n        discovery = {\n          ...retried,\n          scrollAttempts: firstDiscovery.scrollAttempts,\n          scrollStable: firstDiscovery.scrollStable,\n        };\n      } else {\n        discovery = retried;\n      }\n    }\n    if (discovery?.authRequired) {\n      throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn thread-snapshot requires an active signed-in LinkedIn browser session.');\n    }\n    if (!discovery || typeof discovery !== 'object' || Array.isArray(discovery) || !Array.isArray(discovery.apiUrls)) {\n      throw new CommandExecutionError('LinkedIn thread-snapshot returned a malformed API discovery payload.');\n    }\n\n    const actualUrl = canonicalizeLinkedInThreadUrl(discovery.url || '');\n    if (threadUrl && actualUrl && threadUrl !== actualUrl) {\n      throw new CommandExecutionError('LinkedIn thread-snapshot blocked: thread_url_mismatch', `Expected ${threadUrl}; actual ${actualUrl}`);\n    }\n    if (maxScrolls >= 4 && discovery.scrollAttempts >= maxScrolls && discovery.scrollStable === false) {\n      throw new CommandExecutionError('LinkedIn thread history did not stabilize before --max-scrolls; refusing to return a partial snapshot.');\n    }\n\n    const apiUrls = validateThreadApiUrls(discovery.apiUrls, threadUrl);\n    const csrf = await requireLinkedInCookie(page, 'LinkedIn thread-snapshot');\n    const fetched = unwrapEvaluateResult(\n      await page.evaluate(buildFetchThreadPagesScript(apiUrls, csrf)),\n    );","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L318-L354","documentation":"After discovery, if the payload reports authRequired for the LinkedIn domain, the command throws AuthRequiredError because messengerMessages API interception only works inside a signed-in session. This is the library's explicit signal that your LinkedIn cookies/session expired or the page was redirected to login.","triggerScenarios":"Running with expired/invalid LinkedIn session cookies; LinkedIn redirecting the browser to the login wall; using a profile that was signed out between runs; hitting LinkedIn's auth challenge after suspicious activity.","commonSituations":"Long-lived automation sessions whose cookies aged out; running from a new IP triggering re-auth; sharing accounts across machines invalidating sessions; rate-limit-driven logout.","solutions":["Re-authenticate: sign in to LinkedIn in the browser session and refresh cookies before re-running","Load fresh cookies from a recently signed-in browser profile into your session store","Check whether LinkedIn is showing a security challenge and complete it manually once","Avoid hammering the endpoint — back off if repeated runs trigger forced re-login"],"exampleFix":"// before: stale cookie jar\nsession.cookies = staleCookies;\nawait run('linkedin thread-snapshot', { 'thread-url': url });\n// after: refresh cookies from an authenticated profile first\nsession.cookies = await loadFreshLinkedInCookies();\nawait run('linkedin thread-snapshot', { 'thread-url': url });","handlingStrategy":"try-catch","validationCode":"// Before running, verify the session is signed in\nconst res = await page.goto('https://www.linkedin.com/feed/');\nif (/login|checkpoint/.test(res.url())) {\n  throw new Error('LinkedIn session expired; re-authenticate first');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const snap = await run('linkedin thread-snapshot', { 'thread-url': url });\n} catch (err) {\n  if (err instanceof AuthRequiredError || String(err.message).includes('signed-in LinkedIn browser session')) {\n    await refreshLinkedInSession(); // sign in / reload cookies, then retry once\n  } else throw err;\n}","preventionTips":["Refresh LinkedIn cookies regularly in long-running automations","Detect login-wall redirects before running commands","Complete LinkedIn security challenges promptly; avoid high request rates"],"tags":["linkedin","authentication","session-expired"],"backgroundTag":"auth-session-expired","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}