jackwener/OpenCLI · error · CommandExecutionError
LinkedIn connect blocked: ${safety.blockReason}
Error message
LinkedIn connect blocked: ${safety.blockReason} What it means
assessProfileSafety compares the observed profile against the expected name and connectability. If safety checks fail for any reason other than auth or routine non-connectability (e.g. wrong profile, page did not render, unexpected URL), the command throws CommandExecutionError with the safety blockReason as the message and diagnostic details (expected vs actual name, observed URL, visible buttons) as secondary info.
Source
Thrown at clis/linkedin/connect.js:440
// The name resolves early (from document.title), but the profile action
// buttons (Connect / Message / Pending) render later. Keep probing until
// the action state has resolved, not merely until the name is visible.
for (let attempt = 0; attempt < 8; attempt += 1) {
const resolved = probe?.name
&& (probe.connectAvailable || probe.alreadyConnected || probe.pending || probe.moreAvailable);
if (resolved) break;
await page.wait(2);
probe = await probeProfile(page, expectedName);
}
const safety = assessProfileSafety(probe, expectedName, profileUrl);
if (safety.blockReason === 'auth_required') {
throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn connect requires an active signed-in LinkedIn browser session.');
}
if (!safety.ok && safety.safety === 'routine_non_connectable') {
return [{ status: 'not_connectable', recipient: safety.actualValue, reason: safety.blockReason, profile_url: safety.observedUrl, note_chars: note.length, connectable: false }];
}
if (!safety.ok) {
throw new CommandExecutionError(
`LinkedIn connect blocked: ${safety.blockReason}`,
`Expected ${safety.expectedValue}; actual ${safety.actualValue || 'not_visible'} at ${safety.observedUrl || 'url_not_available'}\nButtons: ${(probe?.buttonLabels || []).join(' | ')}`,
);
}
if (!args.send) {
return [{ status: 'connectable_dry_run', recipient: safety.actualValue, reason: safety.blockReason, profile_url: safety.observedUrl, note_chars: note.length, connectable: true }];
}
const inviteHref = probe?.connectHref || '';
if (inviteHref) {
// Anchor-based Connect: navigate straight to the invitation route, where the
// "Add a note?" dialog renders already open.
const inviteUrl = canonicalizeLinkedInInviteUrl(inviteHref);
if (!inviteUrl) {
throw new CommandExecutionError('LinkedIn connect blocked: invalid_connect_link');
}
await page.goto(inviteUrl);
await page.wait(6);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Verify --expected-name matches the profile's current display name exactly (or relax expected-name if the library allows)
- Load the profile URL manually in a browser to confirm it still exists and shows the expected person
- Increase patience/retry waits if the page is slow, then re-run
- Update the library if LinkedIn layout drift is breaking probeProfile's selectors
Example fix
// before --profile-url "https://www.linkedin.com/in/jane-doe/" --expected-name "Janet Doe" // after --profile-url "https://www.linkedin.com/in/jane-doe/" --expected-name "Jane Doe"
Defensive patterns
Strategy: try-catch
Validate before calling
const expected = (args['expected-name'] || '').trim();
if (!expected) throw new Error('--expected-name must match the profile display name exactly');
// optionally pre-fetch the page and confirm the h1 matches expected before automation Type guard
null
Try / catch
try { await runConnect(args); } catch (e) { if (String(e.message).startsWith('LinkedIn connect blocked:')) { console.error(e.message, e.secondary || ''); /* inspect expected/actual diagnostics */ } else { throw e; } } Prevention
- Keep --expected-name in sync with the profile's current display name
- Verify the profile URL resolves to the intended person before automating
- Allow generous page-load waits on slow networks
- Update the library when LinkedIn markup drift breaks probes
When it happens
Trigger: The loaded page's visible name does not match --expected-name; the profile URL redirected elsewhere; the profile page failed to render its identity elements; probe returned no recognizable profile structure.
Common situations: Typos or stale --expected-name vs a renamed profile; profile deleted/private/redirected; LinkedIn layout drift breaking the probe; slow load leaving the probe to read an intermediate page.
Related errors
- LinkedIn connect blocked: invalid_connect_link
- LinkedIn connect blocked: ${opened?.reason || 'connect_contr
- LinkedIn connect blocked: ${result?.reason || 'send_failed'}
- Could not find Antigravity input box
- Could not find input box
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5a20670dd8e86cfa.
Report an issue: GitHub.