{"record":{"id":"b13db3216a565326","repo":"jackwener/OpenCLI","slug":"linkedin-learning-feedrecommendationgroups-returne-b13db3","errorCode":null,"errorMessage":"LinkedIn Learning feedRecommendationGroups returned no parseable cards with slug identity","messagePattern":"LinkedIn Learning feedRecommendationGroups returned no parseable cards with slug identity","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin-learning/trending.js","lineNumber":77,"sourceCode":"                const cards = Array.isArray(carousel?.cards) ? carousel.cards : [];\n                for (const card of cards) {\n                    sawCards = true;\n                    if (rows.length >= limit) break;\n                    const slug = card?.slug;\n                    if (!slug || seen.has(slug)) continue;\n                    seen.add(slug);\n                    const row = parseCard(card, carousel, rank);\n                    if (!row) continue;\n                    rows.push(row);\n                    rank += 1;\n                }\n                if (rows.length >= limit) break;\n            }\n            if (rows.length >= limit) break;\n        }\n        if (rows.length === 0) {\n            if (sawCards) {\n                throw new CommandExecutionError('LinkedIn Learning feedRecommendationGroups returned no parseable cards with slug identity');\n            }\n            throw new EmptyResultError('LinkedIn Learning returned no personalized recommendations');\n        }\n        return rows;\n    },\n});\n\nexport const __test__ = { parseCard };\n","sourceCodeStart":59,"sourceCodeEnd":86,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin-learning/trending.js#L59-L86","documentation":"The trending command scraped LinkedIn Learning's feedRecommendationGroups HTML and saw at least one card node (sawCards true) but could not extract any usable row: no card carried a parseable slug identity. The library throws CommandExecutionError to distinguish 'LinkedIn changed/obfuscated its markup or cards lack slugs' from 'genuinely empty recommendations' (EmptyResultError).","triggerScenarios":"Calling the linkedin-learning trending command when the feedRecommendationGroups payload contains card elements but parseCard fails to derive a slug from every one of them, so rows stays empty while sawCards is true.","commonSituations":"LinkedIn changed its feed card markup or slug attribute names; a partially rendered feed where cards exist but hrefs/slugs are absent; a session/region variant serving a different layout; scraping a deprecated feed component.","solutions":["Re-authenticate with a fresh LinkedIn session (run the site auth flow) so the real personalized feed renders.","Update the library to a version that matches current LinkedIn Learning markup.","Confirm the account actually has personalized recommendations (open LinkedIn Learning in a browser) — new/empty accounts may serve slug-less promo cards.","Retry later if LinkedIn is mid-rollout of a layout change; check the project issue tracker."],"exampleFix":"// before\nlinkedin trending --site linkedin-learning   // throws 'no parseable cards with slug identity'\n// after\nlinkedin auth linkedin                        // refresh li_at session\nlinkedin trending --site linkedin-learning    // cards now parse","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  const rows = await run('linkedin-learning trending');\n} catch (e) {\n  if (/no parseable cards with slug identity/.test(e.message)) {\n    // scraper markup mismatch: alert maintainers or fall back to another source\n  } else if (e.name === 'EmptyResultError') {\n    return [];\n  }\n  throw e;\n}","preventionTips":["Keep the library updated against LinkedIn markup changes.","Run the auth flow first so the real feed renders.","Distinguish EmptyResultError from CommandExecutionError when handling."],"tags":["scraping","markup-change","parse-failure"],"backgroundTag":"scraper-markup-change","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}