{"record":{"id":"987a0817e5dc9d53","repo":"jackwener/OpenCLI","slug":"linkedin-messengermessages-api-returned-a-malforme-987a08","errorCode":null,"errorMessage":"LinkedIn messengerMessages API returned a malformed normalized payload.","messagePattern":"LinkedIn messengerMessages API returned a malformed normalized payload\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":212,"sourceCode":"    }\n  }\n  return apiUrls;\n}\n\nfunction parseThreadPages(pages) {\n  if (!Array.isArray(pages) || pages.length === 0) {\n    throw new CommandExecutionError('LinkedIn messengerMessages API returned no pages.');\n  }\n\n  const entities = new Map();\n  const apiUrls = [];\n  for (const page of pages) {\n    if (!page || typeof page !== 'object' || Array.isArray(page) || typeof page.url !== 'string') {\n      throw new CommandExecutionError('LinkedIn messengerMessages API returned a malformed page wrapper.');\n    }\n    const normalized = page.json;\n    if (!normalized || typeof normalized !== 'object' || Array.isArray(normalized)) {\n      throw new CommandExecutionError('LinkedIn messengerMessages API returned a malformed normalized payload.');\n    }\n    if (Array.isArray(normalized.errors) && normalized.errors.length > 0) {\n      throw new CommandExecutionError('LinkedIn messengerMessages GraphQL returned errors.');\n    }\n    if (!Array.isArray(normalized.included)) {\n      throw new CommandExecutionError('LinkedIn messengerMessages payload is missing the included entity array.');\n    }\n    const data = normalized.data?.data;\n    if (!data || typeof data !== 'object' || Array.isArray(data)) {\n      throw new CommandExecutionError('LinkedIn messengerMessages payload is missing normalized data.');\n    }\n    const container = Object.entries(data).find(([key, value]) => (\n      /^messengerMessages/i.test(key)\n      && value\n      && typeof value === 'object'\n      && !Array.isArray(value)\n      && (Array.isArray(value['*elements']) || Array.isArray(value.elements))\n    ));","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L194-L230","documentation":"Thrown by parseThreadPages when a page's normalized payload (page.json) is missing, not an object, or an array. The library expects LinkedIn's 'normalized+json' document — a plain object containing included/data — and refuses to parse anything else rather than producing a partial snapshot.","triggerScenarios":"page.json is null/undefined (JSON parse failed upstream and a placeholder was pushed), a JSON array was returned, or page.json is a string/number because the caller stored the raw text.","commonSituations":"LinkedIn returned a non-normalized payload (e.g. an HTML error page parsed into a string); the accept header 'application/vnd.linkedin.normalized+json+2.1' was dropped in a customized fetch; a proxy intercepted and re-encoded the response.","solutions":["Re-run so the fetch script replays the request with the original headers, especially accept: application/vnd.linkedin.normalized+json+2.1.","Confirm the response content-type was JSON/normalized before pushing into pages (the fetch script already checks this — don't bypass it).","Inspect page.json in devtools for a LinkedIn error/interstitial body and address that cause (auth wall, rate limit, endpoint change)."],"exampleFix":"// before: storing raw text\npages.push({ url, json: await response.text() });\n// after: parse JSON like the library does\npages.push({ url, json: await response.json() });","handlingStrategy":"type-guard","validationCode":"const ok = pages.every((p) => p.json && typeof p.json === 'object' && !Array.isArray(p.json));\nif (!ok) throw new Error('page.json must be a normalized JSON object');","typeGuard":"function isNormalizedObject(v) {\n  return Boolean(v) && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const snapshot = await cli.linkedin.threadSnapshot({ url: threadUrl });\n} catch (err) {\n  if (err.message.includes('malformed normalized payload')) {\n    // retry with the normalized vendor accept header; inspect for auth walls/rate limits\n  } else throw err;\n}","preventionTips":["Always request accept: application/vnd.linkedin.normalized+json+2.1.","Do not bypass the fetch script's content-type check.","Watch for LinkedIn envelope changes and update the expected format promptly."],"tags":["linkedin","schema-validation","payload-shape","scraping"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}