{"record":{"id":"9c9a97c56adf8ae2","repo":"jackwener/OpenCLI","slug":"linkedin-messengermessages-payload-is-missing-the","errorCode":null,"errorMessage":"LinkedIn messengerMessages payload is missing the included entity array.","messagePattern":"LinkedIn messengerMessages payload is missing the included entity array\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":218,"sourceCode":"  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    ));\n    if (!container) {\n      throw new CommandExecutionError('LinkedIn messengerMessages payload is missing a message collection.');\n    }\n    for (const entity of normalized.included) {\n      if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {\n        throw new CommandExecutionError('LinkedIn messengerMessages payload contains a malformed included entity.');","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L200-L236","documentation":"Thrown by parseThreadPages when the normalized payload lacks an 'included' array. LinkedIn's normalized JSON format stores denormalized entities (messages, participants) in 'included'; without it the library cannot reconstruct message text or participants and refuses to return an empty snapshot.","triggerScenarios":"normalized.included is undefined, null, or not an array — e.g. the endpoint returned a different envelope version, a stub/empty GraphQL response with data but no included, or the JSON was produced by a non-normalized API response.","commonSituations":"LinkedIn changed its normalized+json envelope version; the accept header requested a different format version; the thread was deleted so the server returned an empty envelope; a custom fetch accepted application/json instead of the normalized vendor type.","solutions":["Ensure the fetch uses accept: application/vnd.linkedin.normalized+json+2.1 so LinkedIn returns the normalized envelope with 'included'.","Reload the thread page and rerun so discovery replays the exact requests the live app made.","If LinkedIn changed envelope versions, update the accept header and parsing to the new format."],"exampleFix":"// before\nheaders: { 'csrf-token': csrf, accept: 'application/json' },\n// after\nheaders: { 'csrf-token': csrf, accept: 'application/vnd.linkedin.normalized+json+2.1' },","handlingStrategy":"type-guard","validationCode":"if (!Array.isArray(json?.included)) throw new Error('Normalized payload missing included[] — check accept header/format version');","typeGuard":"function hasIncludedEntities(json) {\n  return Array.isArray((json)?.included);\n}","tryCatchPattern":"try {\n  const snapshot = await cli.linkedin.threadSnapshot({ url: threadUrl });\n} catch (err) {\n  if (err.message.includes('missing the included entity array')) {\n    // retry with the normalized+json+2.1 accept header; verify envelope version\n  } else throw err;\n}","preventionTips":["Keep accept: application/vnd.linkedin.normalized+json+2.1 on all replayed requests.","Verify the payload envelope in devtools after any LinkedIn UI update.","Don't substitute plain application/json for the normalized vendor type."],"tags":["linkedin","schema-validation","payload-shape","scraping"],"backgroundTag":"missing-required-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}