jackwener/OpenCLI · error · CommandExecutionError
LinkedIn messengerMessages payload is missing the included e
Error message
LinkedIn messengerMessages payload is missing the included entity array.
What it means
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.
Source
Thrown at clis/linkedin/thread-snapshot.js:218
if (!Array.isArray(pages) || pages.length === 0) {
throw new CommandExecutionError('LinkedIn messengerMessages API returned no pages.');
}
const entities = new Map();
const apiUrls = [];
for (const page of pages) {
if (!page || typeof page !== 'object' || Array.isArray(page) || typeof page.url !== 'string') {
throw new CommandExecutionError('LinkedIn messengerMessages API returned a malformed page wrapper.');
}
const normalized = page.json;
if (!normalized || typeof normalized !== 'object' || Array.isArray(normalized)) {
throw new CommandExecutionError('LinkedIn messengerMessages API returned a malformed normalized payload.');
}
if (Array.isArray(normalized.errors) && normalized.errors.length > 0) {
throw new CommandExecutionError('LinkedIn messengerMessages GraphQL returned errors.');
}
if (!Array.isArray(normalized.included)) {
throw new CommandExecutionError('LinkedIn messengerMessages payload is missing the included entity array.');
}
const data = normalized.data?.data;
if (!data || typeof data !== 'object' || Array.isArray(data)) {
throw new CommandExecutionError('LinkedIn messengerMessages payload is missing normalized data.');
}
const container = Object.entries(data).find(([key, value]) => (
/^messengerMessages/i.test(key)
&& value
&& typeof value === 'object'
&& !Array.isArray(value)
&& (Array.isArray(value['*elements']) || Array.isArray(value.elements))
));
if (!container) {
throw new CommandExecutionError('LinkedIn messengerMessages payload is missing a message collection.');
}
for (const entity of normalized.included) {
if (!entity || typeof entity !== 'object' || Array.isArray(entity)) {
throw new CommandExecutionError('LinkedIn messengerMessages payload contains a malformed included entity.');View on GitHub (pinned to 49907e53dc)
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.
Example fix
// before
headers: { 'csrf-token': csrf, accept: 'application/json' },
// after
headers: { 'csrf-token': csrf, accept: 'application/vnd.linkedin.normalized+json+2.1' }, Defensive patterns
Strategy: type-guard
Validate before calling
if (!Array.isArray(json?.included)) throw new Error('Normalized payload missing included[] — check accept header/format version'); Type guard
function hasIncludedEntities(json) {
return Array.isArray((json)?.included);
} Try / catch
try {
const snapshot = await cli.linkedin.threadSnapshot({ url: threadUrl });
} catch (err) {
if (err.message.includes('missing the included entity array')) {
// retry with the normalized+json+2.1 accept header; verify envelope version
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- LinkedIn messengerMessages API returned a malformed normaliz
- LinkedIn jobs preferences returned malformed preferences pay
- LinkedIn jobs preferences returned malformed alerts payload
- LinkedIn people search returned malformed extraction payload
- LinkedIn people search returned malformed row at index ${ind
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9c9a97c56adf8ae2.
Report an issue: GitHub.