jackwener/OpenCLI · error · CommandExecutionError

LinkedIn Learning searchV2 returned no parseable rows with s

Error message

LinkedIn Learning searchV2 returned no parseable rows with slug identity

What it means

Thrown after iterating the searchV2 elements when zero rows could be parsed into records carrying a slug identity. Unlike the empty-elements case, elements existed but every element failed parseRow — meaning the per-element shape changed or lacks the identity fields the parser keys on.

Source

Thrown at clis/linkedin-learning/search.js:88

        const result = await fetchLinkedInLearningApi(page, url);
        if (!result?.json) {
            throw new CommandExecutionError(`LinkedIn Learning searchV2 failed: ${result?.error ?? 'no payload'}`);
        }
        const elements = result.json?.elements;
        if (!Array.isArray(elements)) {
            throw new CommandExecutionError('LinkedIn Learning searchV2 returned malformed payload: missing elements array');
        }
        if (elements.length === 0) {
            throw new EmptyResultError(`No LinkedIn Learning results for "${keywords}"`);
        }
        const rows = [];
        for (const el of elements) {
            if (rows.length >= limit) break;
            const row = parseRow(el, rows.length + 1);
            if (row) rows.push(row);
        }
        if (rows.length === 0) {
            throw new CommandExecutionError('LinkedIn Learning searchV2 returned no parseable rows with slug identity');
        }
        return rows;
    },
});

export const __test__ = {
    parseAuthors,
    durationSeconds,
    averageRating,
    parseRow,
};

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Dump one raw element (result.json.elements[0]) and compare its shape to parseRow's expectations.
  2. Update the CLI to a version whose parseRow matches the current searchV2 element schema.
  3. Extend parseRow to handle the new element shape while preserving slug identity extraction.
  4. Confirm via the web UI that normal course results exist for the query (rules out an all-ads payload).

Example fix

// before
const row = parseRow(el, rows.length + 1);
// after
const row = parseRow(el, rows.length + 1) ?? parseRowV2(el, rows.length + 1);
Defensive patterns

Strategy: type-guard

Validate before calling

// verify at least one element carries identifiable fields before parsing
const identifiable = elements.filter(el => el && (el.slug || el.entityUrn || el.title));
if (identifiable.length === 0) throw new Error('No identifiable course elements in payload');

Type guard

function hasSlugIdentity(el) {
  return !!el && typeof el === 'object' &&
    typeof (el.slug ?? el.entityUrn) === 'string' && (el.slug ?? el.entityUrn).length > 0;
}

Try / catch

try {
  const rows = await search(page, { keywords });
} catch (e) {
  if (e.message.includes('no parseable rows')) {
    console.error('Element schema changed; dump elements[0] and update parseRow');
  } else throw e;
}

Prevention

When it happens

Trigger: All elements in the payload lack the fields parseRow needs to extract a course slug/identity (e.g. LinkedIn renamed entity subtypes, moved 'lockedValue'/'title'/'slug' fields, or elements contain only sponsored/ads entries).

Common situations: LinkedIn Learning schema drift in element structure (new entity version), a payload consisting entirely of non-course elements, or an outdated CLI parser lagging behind the current API shape.

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