jackwener/OpenCLI · error · CommandExecutionError

LinkedIn people search returned malformed extraction payload

Error message

LinkedIn people search returned malformed extraction payload: missing rows array

What it means

CommandExecutionError thrown by normalizePeopleRows when the payload extracted from the people-search results page is not an array. The extraction script is expected to return an array of row objects; anything else (null, object, string) indicates the scrape failed to find result rows in the expected structure.

Source

Thrown at clis/linkedin/people-search.js:51

function normalizeProfileUrl(value) {
    const raw = normalizeWhitespace(value);
    if (!raw) return '';
    try {
        const parsed = new URL(raw);
        const host = parsed.hostname.toLowerCase();
        if (parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.port) return '';
        if (host !== 'linkedin.com' && host !== 'www.linkedin.com') return '';
        const match = parsed.pathname.match(/^\/in\/([^/?#]+)\/?$/);
        if (!match || !match[1]) return '';
        return `https://www.linkedin.com/in/${match[1]}/`;
    } catch {
        return '';
    }
}

function normalizePeopleRows(rows) {
    if (!Array.isArray(rows)) {
        throw new CommandExecutionError('LinkedIn people search returned malformed extraction payload: missing rows array');
    }
    return rows.map((row, index) => {
        if (!row || typeof row !== 'object') {
            throw new CommandExecutionError(`LinkedIn people search returned malformed row at index ${index}`);
        }
        const name = normalizeWhitespace(row.name);
        const profileUrl = normalizeProfileUrl(row.profile_url);
        if (!name || !profileUrl) {
            throw new CommandExecutionError(`LinkedIn people search returned row without stable profile identity at index ${index}`);
        }
        return {
            name,
            headline: normalizeWhitespace(row.headline),
            location: normalizeWhitespace(row.location),
            profile_url: profileUrl,
        };
    });
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-authenticate so the authenticated search page loads
  2. Increase the wait after navigating to SEARCH_URL_BASE so results render
  3. Handle the zero-results case by returning [] when the empty-state DOM is detected and update the extraction script for current markup
  4. Log the raw evaluate payload to confirm which shape came back

Example fix

// before
const rows = unwrapEvaluateResult(await page.evaluate(buildSearchScript()));
return normalizePeopleRows(rows);
// after
const raw = unwrapEvaluateResult(await page.evaluate(buildSearchScript()));
const rows = Array.isArray(raw) ? raw : (raw && Array.isArray(raw.rows) ? raw.rows : []);
return normalizePeopleRows(rows);
Defensive patterns

Strategy: type-guard

Validate before calling

const raw = unwrapEvaluateResult(await page.evaluate(buildSearchScript()));
if (!Array.isArray(raw)) {
  console.error('extraction did not return an array — check auth page redirect or empty results');
}

Type guard

function isRowsArray(v) {
  return Array.isArray(v) && v.every((r) => r && typeof r === 'object');
}

Try / catch

try {
  return normalizePeopleRows(rows);
} catch (err) {
  if (String(err.message).includes('missing rows array')) {
    await assertLinkedInAuthenticated(page, 'people search');
    await page.wait(5);
    rows = unwrapEvaluateResult(await page.evaluate(buildSearchScript()));
    return normalizePeopleRows(rows);
  }
  throw err;
}

Prevention

When it happens

Trigger: page.evaluate returning a non-array because the search results list was absent — authwall/guest page, zero results rendering a different DOM, or LinkedIn markup change breaking the rows collector.

Common situations: Expired cookies redirecting to login; search query with no matches producing an empty-state DOM the script can't collect; LinkedIn search UI redesign; insufficient wait before evaluate.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/743cf07c4ebf32cd. Report an issue: GitHub.