jackwener/OpenCLI · error · CommandExecutionError

LinkedIn people search returned row without stable profile i

Error message

LinkedIn people search returned row without stable profile identity at index ${index}

What it means

CommandExecutionError thrown by normalizePeopleRows when a row lacks a stable identity: after normalization both name and profile_url are empty/missing. Identity fields are mandatory because downstream consumers key results off them, so rows without either are rejected with the index in the message.

Source

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

        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,
        };
    });
}

function parseNonNegativeCount(value, label) {
    const count = Number(value);
    if (!Number.isInteger(count) || count < 0) {
        throw new CommandExecutionError(`LinkedIn people search returned malformed extraction payload: invalid ${label}`);
    }
    return count;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Update the extraction script to target the current name and profile-link selectors
  2. Relax/extend normalizeProfileUrl to accept the new URL form and resolve relative links
  3. Skip identity-less rows instead of failing the whole batch
  4. Wait longer before extraction so lazy-loaded name/link elements are present

Example fix

// before
if (!name || !profileUrl) {
  throw new CommandExecutionError(`LinkedIn people search returned row without stable profile identity at index ${index}`);
}
// after
if (!name || !profileUrl) {
  console.warn(`skipping row ${index}: missing identity`);
  return null;
}
... .filter(Boolean);
Defensive patterns

Strategy: validation

Validate before calling

function hasStableIdentity(row) {
  const name = (row && typeof row.name === 'string') ? row.name.trim() : '';
  const url = (row && typeof row.profile_url === 'string') ? row.profile_url.trim() : '';
  return Boolean(name && url);
}
const usable = rawRows.filter(hasStableIdentity);

Type guard

function isIdentifiedPerson(row) {
  return typeof row === 'object' && row !== null && typeof row.name === 'string' && row.name.trim() !== '' && typeof row.profile_url === 'string' && row.profile_url.trim() !== '';
}

Try / catch

try {
  return normalizePeopleRows(rows);
} catch (err) {
  const m = String(err.message).match(/without stable profile identity at index (\d+)/);
  if (m) {
    rows.splice(Number(m[1]), 1);
    return normalizePeopleRows(rows);
  }
  throw err;
}

Prevention

When it happens

Trigger: A scraped row where row.name normalizes to '' or row.profile_url fails normalizeProfileUrl — e.g. rows from a results DOM variant with the name in a different node, or profile links rendered as relative/obfuscated URLs the normalizer rejects.

Common situations: LinkedIn serves different card markup for some results (e.g. company cards mixed into people results); privacy-restricted profiles hiding the name; normalizeProfileUrl too strict for new link formats (e.g. /in/name/ vs new tracking-wrapped URLs).

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/ece15e883b49684e. Report an issue: GitHub.