jackwener/OpenCLI · info · EmptyResultError

No LinkedIn Learning results for "${keywords}"

Error message

No LinkedIn Learning results for "${keywords}"

What it means

An EmptyResultError thrown when searchV2 legitimately returns an elements array that contains zero items. This is not a failure of the transport or schema — the query simply matched nothing. It lets the CLI exit with a distinct 'empty' code instead of an error.

Source

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

    ],
    columns: ['rank', 'type', 'title', 'instructor', 'difficulty', 'duration_sec', 'rating', 'rating_count', 'viewers', 'url'],
    func: async (page, args) => {
        if (!page) throw new CommandExecutionError('Browser session required for linkedin-learning search');
        const keywords = normalizeWhitespace(args.keywords);
        if (!keywords) throw new ArgumentError('--keywords is required');
        const limit = parseLimit(args.limit);

        const url = `https://www.linkedin.com/learning-api/searchV2?keywords=${encodeURIComponent(keywords)}&q=keywords`;
        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,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Simplify or broaden the --keywords value and retry.
  2. Check spelling and try English keyword variants.
  3. Verify in the LinkedIn Learning web UI that searching the same term returns results.
  4. Treat as an empty result in calling scripts (check for EmptyResultError separately from real errors).

Example fix

// before
clio linkedin-learning search --keywords "xjs9z niche gibberish"
// after
clio linkedin-learning search --keywords "javascript"
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check keywords before invoking
const kw = keywords.trim();
if (!kw || kw.length < 2) throw new Error('Provide meaningful search keywords');

Try / catch

try {
  const rows = await search(page, { keywords });
} catch (e) {
  if (e.name === 'EmptyResultError') return []; // empty is not a failure
  throw e;
}

Prevention

When it happens

Trigger: A keywords value that matches no LinkedIn Learning courses (misspellings, very niche or non-English terms, or terms LinkedIn does not index), or a filters/region context where no content is available to the signed-in account.

Common situations: Typo'd search keywords, searching for content unavailable in the account's locale/region, or content removed from the catalog.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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