{"record":{"id":"806f4d8502e95876","repo":"jackwener/OpenCLI","slug":"linkedin-messengermessages-payload-contains-a-malf","errorCode":null,"errorMessage":"LinkedIn messengerMessages payload contains a malformed included entity.","messagePattern":"LinkedIn messengerMessages payload contains a malformed included entity\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":236,"sourceCode":"      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.');\n      }\n      if (entity.entityUrn) {\n        const existing = entities.get(entity.entityUrn);\n        if (!existing || Object.keys(entity).length > Object.keys(existing).length) {\n          entities.set(entity.entityUrn, entity);\n        }\n      }\n    }\n    apiUrls.push(page.url);\n  }\n\n  const ownerUrn = ownerUrnFromApiUrls(apiUrls);\n  if (!ownerUrn) {\n    throw new CommandExecutionError('LinkedIn messengerMessages URL is missing the conversation owner identity.');\n  }\n\n  const participants = Array.from(entities.values()).filter(\n    (entity) => entity.$type === 'com.linkedin.messenger.MessagingParticipant',","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L218-L254","documentation":"parseThreadPages validates every entry of the LinkedIn messengerMessages GraphQL `included` array. The library throws this error when any element of `included` is null, not an object, or an array, because entity extraction relies on reading per-entity fields like entityUrn and $type. A malformed element means LinkedIn's payload shape changed or was corrupted, and proceeding could silently drop or misattribute message data.","triggerScenarios":"A captured messengerMessages page has an `included` array containing null, a primitive, or a nested array element instead of entity objects — typically after LinkedIn changes its Voyager GraphQL response format or a truncated/proxied response.","commonSituations":"Running with an outdated CLI against a new LinkedIn API schema; using HTTP mocks/fixtures recorded from a different API version; middleman proxies or HTML error pages injected into a captured network response.","solutions":["Update the CLI/library to the latest version so parsers match LinkedIn's current messengerMessages schema","Re-capture the thread (re-run the command) — transient truncation or injected error pages often resolve on retry","Inspect the captured response payload and confirm `included` contains only entity objects; if scraping yourself, sanitize entries before parsing","If using a proxy, disable response rewriting/HTML injection for voyager API calls"],"exampleFix":"// before: pages captured by an older scraper with array-shaped included entries\nconst normalized = page.json; // included: [ ['urn:li:msg:1'], {...} ]\n// after: upgrade the capture script / re-record pages so each included entry is an entity object\nconst normalized = page.json; // included: [ { entityUrn: 'urn:li:msg:1', $type: '...' }, {...} ]","handlingStrategy":"validation","validationCode":"function isValidIncluded(payload) {\n  return !!payload && Array.isArray(payload.included)\n    && payload.included.every(e => e && typeof e === 'object' && !Array.isArray(e));\n}\nif (!pages.every(p => p?.json && isValidIncluded(p.json))) throw new Error('Malformed included entities before calling CLI');","typeGuard":"const isEntity = (e) => !!e && typeof e === 'object' && !Array.isArray(e);","tryCatchPattern":"try {\n  await run('linkedin thread-snapshot', { 'thread-url': url });\n} catch (err) {\n  if (String(err.message).includes('malformed included entity')) {\n    // payload shape drift: re-capture or upgrade library\n  } else throw err;\n}","preventionTips":["Keep the CLI updated against LinkedIn schema changes","Re-capture threads rather than reusing old recorded payloads","Validate recorded fixtures' included arrays before replaying them"],"tags":["linkedin","payload-validation","schema-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}