{"record":{"id":"13354e5904a9af00","repo":"jackwener/OpenCLI","slug":"browser-session-required-for-linkedin-connect","errorCode":null,"errorMessage":"Browser session required for linkedin connect","messagePattern":"Browser session required for linkedin connect","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/connect.js","lineNumber":414,"sourceCode":"}\n\ncli({\n    site: 'linkedin',\n    name: 'connect',\n    access: 'write',\n    description: 'Fail-closed LinkedIn connection request sender that verifies the exact profile before optionally sending a note',\n    domain: LINKEDIN_DOMAIN,\n    strategy: Strategy.UI,\n    browser: true,\n    args: [\n        { name: 'profile-url', type: 'string', required: true, positional: true, help: 'Exact LinkedIn profile URL to open and verify' },\n        { name: 'expected-name', type: 'string', required: true, help: 'Expected visible profile name' },\n        { name: 'note', type: 'string', required: false, default: '', help: 'Optional connection note, max 300 chars' },\n        { name: 'send', type: 'bool', required: false, default: false, help: 'Actually click Send. Default is dry-run verification only.' },\n    ],\n    columns: ['status', 'recipient', 'reason', 'profile_url', 'note_chars', 'connectable', 'delivery_verified', 'matched_invitation_name', 'matched_invitation_url', 'actualValue', 'blockReason', 'expectedValue', 'observedUrl', 'safety'],\n    func: async (page, args) => {\n        if (!page) throw new CommandExecutionError('Browser session required for linkedin connect');\n        const profileUrl = requireLinkedInProfileUrl(requireStringArg(args, 'profile-url', '--profile-url'), '--profile-url');\n        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);","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/connect.js#L396-L432","documentation":"The linkedin connect command is a browser-session command: its func receives the active Playwright-like page. If page is null/undefined the command cannot drive LinkedIn and throws CommandExecutionError immediately, before any argument validation.","triggerScenarios":"Invoking the linkedin connect command outside a browser session context — e.g. calling the CLI subcommand directly without launching the headless browser harness, or wiring the command's func with no page argument.","commonSituations":"Running the command through a driver/runner that skips browser session creation; calling the exported command object programmatically with (null, args); misconfigured CLI bootstrap where the browser failed to launch but commands still dispatch.","solutions":["Launch the browser session (the library's browser harness) before invoking linkedin connect","Run the command through the normal CLI entry point so the session is created and passed in","If invoking programmatically, pass a real page instance as the first argument to func","Check earlier logs for browser launch failures (missing browser binary, sandbox issues) that left the session unset"],"exampleFix":"// before\nawait command.func(null, args);\n// after\nconst { page } = await startBrowserSession();\nawait command.func(page, args);","handlingStrategy":"try-catch","validationCode":"if (!page || typeof page.goto !== 'function') throw new Error('Cannot run linkedin connect: no active browser page. Start the browser session first.');","typeGuard":"function hasBrowserPage(p) { return p != null && typeof p.goto === 'function' && typeof p.evaluate === 'function'; }","tryCatchPattern":"try { await connectCommand.func(page, args); } catch (e) { if (String(e.message).includes('Browser session required')) { await startBrowserSession(); /* retry once */ } else { throw e; } }","preventionTips":["Always launch the browser session before invoking browser-scoped commands","Route browser commands through the library's CLI/runner instead of calling func directly","Check startup logs for silent browser-launch failures","Guard programmatic calls with a hasBrowserPage check"],"tags":["browser","session","cli"],"backgroundTag":"browser-session-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}