{"record":{"id":"9fe075143621d433","repo":"jackwener/OpenCLI","slug":"linkedin-connect-requires-an-active-signed-in-link","errorCode":null,"errorMessage":"LinkedIn connect requires an active signed-in LinkedIn browser session.","messagePattern":"LinkedIn connect requires an active signed-in LinkedIn browser session\\.","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/connect.js","lineNumber":434,"sourceCode":"        const expectedName = requireStringArg(args, 'expected-name', '--expected-name');\n        const note = clampNote(args.note || '');\n\n        await page.goto(profileUrl);\n        await page.wait(6);\n        let probe = await probeProfile(page, expectedName);\n        // The name resolves early (from document.title), but the profile action\n        // buttons (Connect / Message / Pending) render later. Keep probing until\n        // the action state has resolved, not merely until the name is visible.\n        for (let attempt = 0; attempt < 8; attempt += 1) {\n            const resolved = probe?.name\n                && (probe.connectAvailable || probe.alreadyConnected || probe.pending || probe.moreAvailable);\n            if (resolved) break;\n            await page.wait(2);\n            probe = await probeProfile(page, expectedName);\n        }\n        const safety = assessProfileSafety(probe, expectedName, profileUrl);\n        if (safety.blockReason === 'auth_required') {\n            throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn connect requires an active signed-in LinkedIn browser session.');\n        }\n        if (!safety.ok && safety.safety === 'routine_non_connectable') {\n            return [{ status: 'not_connectable', recipient: safety.actualValue, reason: safety.blockReason, profile_url: safety.observedUrl, note_chars: note.length, connectable: false }];\n        }\n        if (!safety.ok) {\n            throw new CommandExecutionError(\n                `LinkedIn connect blocked: ${safety.blockReason}`,\n                `Expected ${safety.expectedValue}; actual ${safety.actualValue || 'not_visible'} at ${safety.observedUrl || 'url_not_available'}\\nButtons: ${(probe?.buttonLabels || []).join(' | ')}`,\n            );\n        }\n        if (!args.send) {\n            return [{ status: 'connectable_dry_run', recipient: safety.actualValue, reason: safety.blockReason, profile_url: safety.observedUrl, note_chars: note.length, connectable: true }];\n        }\n        const inviteHref = probe?.connectHref || '';\n        if (inviteHref) {\n            // Anchor-based Connect: navigate straight to the invitation route, where the\n            // \"Add a note?\" dialog renders already open.\n            const inviteUrl = canonicalizeLinkedInInviteUrl(inviteHref);","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/connect.js#L416-L452","documentation":"After navigating to the profile and probing it, the command runs assessProfileSafety. When the probe concludes the page is showing LinkedIn's auth/login wall (blockReason === 'auth_required'), it throws AuthRequiredError rather than attempting to interact with a page the automation cannot see correctly.","triggerScenarios":"The LinkedIn session cookie expired or was never established, so navigating to the profile redirects to a login challenge; the probe sees the sign-in wall and classifies it as auth_required.","commonSituations":"Long-running sessions whose LinkedIn cookies expired; running against a fresh browser profile with no logged-in account; LinkedIn forcing re-authentication / security checkpoint; running from an IP that triggers login walls.","solutions":["Log in to LinkedIn in the browser session (interactive login or restored profile with valid cookies) and re-run the command","Persist/reuse a browser profile directory so cookies survive across runs","Re-authenticate and complete any LinkedIn security checkpoint before automating","Reduce automation rate / use a stable IP if LinkedIn is challenging the session"],"exampleFix":"null","handlingStrategy":"retry","validationCode":"// before running, confirm the session cookie is present in the browser profile\nconst signedIn = await page.evaluate(() => !document.querySelector('a[href*=\"/checkpoint/\"]') && document.querySelector('.global-nav') !== null);\nif (!signedIn) throw new Error('LinkedIn session not signed in — authenticate first.');","typeGuard":"null","tryCatchPattern":"try { await runConnect(args); } catch (e) { if (e instanceof AuthRequiredError || String(e.message).includes('signed-in LinkedIn')) { await interactiveLogin(LINKEDIN_DOMAIN); await runConnect(args); } else { throw e; } }","preventionTips":["Persist a browser profile directory so LinkedIn cookies survive restarts","Re-authenticate before long-running batch jobs","Complete any LinkedIn security checkpoints promptly","Monitor for auth redirects and re-login instead of retrying blindly"],"tags":["authentication","linkedin","session"],"backgroundTag":"auth-session-expired","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}