jackwener/OpenCLI · error · CommandExecutionError
LinkedIn people search returned malformed extraction payload
Error message
LinkedIn people search returned malformed extraction payload
What it means
After a successful evaluate, the command requires result to be a non-null object before validating its numeric fields. If result is null/undefined or a primitive, the extraction produced nothing usable and it throws CommandExecutionError 'LinkedIn people search returned malformed extraction payload'.
Source
Thrown at clis/linkedin/people-search.js:231
throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.');
}
let result;
try {
result = unwrapEvaluateResult(await page.evaluate(extractionScript()));
} catch (error) {
throw new CommandExecutionError(`LinkedIn people search extraction failed: ${error?.message || error}`);
}
if (result?.error) {
if (looksLinkedInAuthWall(`${result.url || ''} ${result.error || ''}`)) {
throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn people search requires an active signed-in browser session.');
}
// If LinkedIn redirected away from the search page that
// usually means CUL was reached or the account is gated.
throw new CommandExecutionError(`LinkedIn redirected away from the search page (${result.error}). Likely Commercial Use Limit reached - the limit resets on the 1st of next month.`);
}
if (!result || typeof result !== 'object') {
throw new CommandExecutionError('LinkedIn people search returned malformed extraction payload');
}
const candidateCount = parseNonNegativeCount(result.candidate_count, 'candidate_count');
parseNonNegativeCount(result.person_entries_count, 'person_entries_count');
const resolvedCount = parseNonNegativeCount(result.resolved_count, 'resolved_count');
const rows = normalizePeopleRows(result.rows);
if (rows.length === 0 && (candidateCount > 0 || resolvedCount > 0)) {
throw new CommandExecutionError('LinkedIn people search found profile candidates but could not parse stable result rows');
}
if (rows.length === 0) {
throw new EmptyResultError(`No people found on the rendered page for "${keywords}". The search may have returned zero results, or the DOM markup may have changed.`);
}
return rows.slice(0, limit).map((p, i) => ({ rank: i + 1, ...p }));
},
});
export const __test__ = {
parseLimit,
buildSearchUrl,View on GitHub (pinned to 49907e53dc)
Solutions
- Update/fix the automation client so page.evaluate returns the object produced by the script
- Ensure unwrapEvaluateResult is used/behaves as intended and doesn't drop object payloads
- Log the raw evaluate result to see what the page actually returned
- Re-run in a signed-in session so the real results page produces a full payload
- If you own the script, guarantee every code path returns the result object
Example fix
// before: script path returns undefined
function extractionScript() { return `() => { if (!document.querySelector('.results')) return; return {...}; }`; }
// after: always return a payload
function extractionScript() { return `() => ({ error: null, rows: [], candidate_count: 0, person_entries_count: 0, resolved_count: 0, ...collect() })`; } Defensive patterns
Strategy: type-guard
Validate before calling
const raw = unwrapEvaluateResult(await page.evaluate(extractionScript()));
if (raw == null || typeof raw !== 'object') throw new Error('extraction returned no object payload'); Type guard
const isExtractionPayload = (v) => v != null && typeof v === 'object' && !Array.isArray(v);
Try / catch
try { const rows = normalizePeopleRows(result.rows); }
catch (e) { if (/malformed extraction payload/.test(e.message)) { return { rows: [], degraded: true }; } throw e; } Prevention
- Guarantee the extraction script always returns an object on every path
- Verify your evaluate wrapper preserves object return values
- Test page adapters/mocks against the real payload contract
- Log raw results when payload shape deviates to catch adapter regressions early
When it happens
Trigger: unwrapEvaluateResult(page.evaluate(extractionScript())) resolves to null, undefined, a string, or a number — e.g. the script returned undefined, the evaluate wrapper stripped the value, or serialization dropped the object.
Common situations: Custom automation client whose evaluate returns undefined for object results; extraction script exiting early and returning undefined; test stubs returning wrong shape; JSON serialization of circular/unserializable data collapsing the result.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- LinkedIn people search returned malformed extraction payload
- LinkedIn sent invitations returned a malformed extraction pa
- LinkedIn cookie lookup returned malformed payload
- LinkedIn people search extraction failed: ${error?.message |
- LinkedIn people search found profile candidates but could no
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9f3618145558d1b7.
Report an issue: GitHub.