{"record":{"id":"849a3c0320dfdc98","repo":"jackwener/OpenCLI","slug":"linkedin-learning-courses-lookup-returned-malforme-849a3c","errorCode":null,"errorMessage":"LinkedIn Learning courses lookup returned malformed course detail: missing title","messagePattern":"LinkedIn Learning courses lookup returned malformed course detail: missing title","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin-learning/course.js","lineNumber":89,"sourceCode":"        if (!page) throw new CommandExecutionError('Browser session required for linkedin-learning course');\n        const slug = parseSlug(args.slug);\n\n        const url = `https://www.linkedin.com/learning-api/courses?q=slug&slug=${encodeURIComponent(slug)}`;\n        const result = await fetchLinkedInLearningApi(page, url);\n        if (!result?.json) {\n            throw new CommandExecutionError(`LinkedIn Learning courses lookup failed: ${result?.error ?? 'no payload'}`);\n        }\n        const elements = result.json?.elements;\n        if (!Array.isArray(elements)) {\n            throw new CommandExecutionError('LinkedIn Learning courses lookup returned malformed payload: missing elements array');\n        }\n        const el = elements[0];\n        if (!el) {\n            throw new EmptyResultError(`No LinkedIn Learning course found for slug \"${slug}\"`);\n        }\n        const row = parseCourse(el, slug);\n        if (!row) {\n            throw new CommandExecutionError('LinkedIn Learning courses lookup returned malformed course detail: missing title');\n        }\n        return [row];\n    },\n});\n\nexport const __test__ = { parseSlug, parseCourse };\n","sourceCodeStart":71,"sourceCodeEnd":96,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin-learning/course.js#L71-L96","documentation":"A course element was returned for the slug, but parseCourse returned null because normalizeWhitespace(el.title) was empty. Since the CLI's primary column is the title, the library treats a title-less course element as a malformed course detail rather than emitting an empty row.","triggerScenarios":"elements[0] exists but lacks a usable title field (missing, null, or whitespace-only el.title, or el.title.text empty), e.g. restricted/placeholder course entries or an API payload-shape change.","commonSituations":"LinkedIn returning partial/teaser course data for region-locked courses; API schema change moving the title to a nested localized object; a draft/unpublished course matched by stale search indexes.","solutions":["Inspect the raw element payload (result.json.elements[0]) to see where the title actually lives.","Retry or pick a different slug — the entry may be a restricted/placeholder course.","If LinkedIn changed the schema, update parseCourse to the new title location and update the library.","Search for the course by title to confirm the correct, fully published slug."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// No caller-side pre-check possible; requires inspecting the API element.\n// Log the raw element to diagnose:\nconsole.debug(JSON.stringify(rawCourseElement?.title));","typeGuard":"function hasTitle(el) {\n  return el != null && typeof el.title === 'string' && el.title.trim().length > 0;\n}","tryCatchPattern":"try {\n  return await runCommand('linkedin-learning', 'course', [slug]);\n} catch (e) {\n  if (e.message.includes('malformed course detail')) {\n    return runCommand('linkedin-learning', 'search', [slugToKeywords(slug)]); // get a better-shaped row\n  }\n  throw e;\n}","preventionTips":["Fall back to search results (which include titles) when detail parsing fails.","Skip slugs that repeatedly return title-less elements (likely restricted placeholders).","Track LinkedIn payload-shape changes and update parsing code promptly."],"tags":["api-response","schema-change","parsing","linkedin-learning"],"backgroundTag":"unexpected-api-schema","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}