jackwener/OpenCLI · error · CommandExecutionError
LinkedIn connections API returned an unexpected response:
Error message
LinkedIn connections API returned an unexpected response:
What it means
If the Voyager connections fetch yields neither authRequired nor valid JSON (fetched falsy, fetched.error set, or fetched.json missing), the command throws CommandExecutionError with the underlying error string. It means the request completed abnormally but was not an authentication problem.
Source
Thrown at clis/linkedin/connections.js:105
const limit = parseLimit(kwargs.limit, 20, 500);
await page.goto('https://www.linkedin.com/mynetwork/invite-connect/connections/');
await page.wait(2);
await assertLinkedInAuthenticated(page, 'linkedin connections');
const csrf = await requireLinkedInCookie(page, 'linkedin connections');
const rows = [];
let start = 0;
while (rows.length < limit) {
const remaining = limit - rows.length;
const count = remaining < PAGE_SIZE ? remaining : PAGE_SIZE;
const url = `${CONNECTIONS_PATH}?start=${start}&count=${count}`;
const fetched = unwrapEvaluateResult(
await page.evaluate(`(${fetchConnections.toString()})(${JSON.stringify(url)}, ${JSON.stringify(csrf)})`),
);
if (fetched && fetched.authRequired) {
throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn connections API authentication failed: ' + fetched.error);
}
if (!fetched || fetched.error || !fetched.json) {
throw new CommandExecutionError('LinkedIn connections API returned an unexpected response: ' + ((fetched && fetched.error) || 'no data'));
}
const elements = fetched.json.elements;
if (!Array.isArray(elements)) {
throw new CommandExecutionError('LinkedIn connections API returned a malformed payload: missing elements array');
}
if (elements.length === 0) break;
for (const element of elements) {
rows.push(mapConnection(element, rows.length));
if (rows.length >= limit) break;
}
start += elements.length;
if (elements.length < count) break;
}
if (rows.length === 0) {
throw new EmptyResultError('linkedin connections', 'No LinkedIn connections were found.');
}
return rows;
},View on GitHub (pinned to 49907e53dc)
Solutions
- Read the appended cause in the message ('HTTP 429', 'fetch failed: ...') and address that specific condition.
- If HTTP 429, wait several minutes and retry with a smaller --limit to reduce page count.
- For HTTP 5xx, retry later or check linkedin.com status; it is server-side.
- Retry once after reloading; transient in-page fetch failures usually clear on a fresh navigation.
Example fix
// before (aggressive pagination) $ opencli linkedin connections --limit 500 CommandExecutionError: LinkedIn connections API returned an unexpected response: HTTP 429 // after $ opencli linkedin connections --limit 40 # fewer requests, spaced out
Defensive patterns
Strategy: retry
Validate before calling
// No pre-call validation possible for transient HTTP failures; check connectivity first.
if (!(await fetch('https://www.linkedin.com', { method: 'HEAD' })).ok) {
throw new Error('linkedin.com unreachable — fix network before calling connections.');
} Type guard
function isTransientHttpFailure(message) {
return /HTTP (429|5\d\d)|fetch failed/i.test(message || '');
} Try / catch
try {
const rows = await opencli.linkedin.connections({ limit: 20 });
} catch (e) {
if (/unexpected response/.test(e.message || '')) {
if (/HTTP 429/.test(e.message)) await new Promise(r => setTimeout(r, 5 * 60_000));
return opencli.linkedin.connections({ limit: 20 }); // single retry
}
throw e;
} Prevention
- Keep --limit modest so pagination stays under rate limits.
- Space out repeated LinkedIn CLI calls; HTTP 429 means back off.
- Re-check the appended cause string to pick the right remedy (429 vs 5xx vs fetch failed).
- Avoid navigating away or closing the page while the fetch runs.
When it happens
Trigger: fetchConnections returns { error: 'HTTP 429' } (rate limit), { error: 'HTTP 5xx' } (server error), { error: 'response was not valid JSON' }, or { error: 'fetch failed: ...' } from a network-level failure inside the page.
Common situations: LinkedIn rate-limiting aggressive pagination (HTTP 429); transient 5xx during a LinkedIn incident; page context destroyed mid-fetch (navigation/close) causing 'fetch failed'; corporate proxy intercepting the response.
Related errors
- arXiv API HTTP ${resp.status}
- Bilibili creator comparison request failed: ${detail}
- coingecko categories returned HTTP ${resp.status}
- ${label} returned HTTP ${resp.status}
- Flomo API returned HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b179fec98dbd54a4.
Report an issue: GitHub.