jackwener/OpenCLI · error · CommandExecutionError
LinkedIn messengerMessages payload is missing normalized dat
Error message
LinkedIn messengerMessages payload is missing normalized data.
What it means
Thrown by parseThreadPages when normalized.data?.data is missing or not a plain object. In LinkedIn's normalized payloads the GraphQL result lives at json.data.data; without it there is no messengerMessages container to locate, so the library cannot extract the element URNs for the thread.
Source
Thrown at clis/linkedin/thread-snapshot.js:222
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.');
}
if (entity.entityUrn) {
const existing = entities.get(entity.entityUrn);
if (!existing || Object.keys(entity).length > Object.keys(existing).length) {View on GitHub (pinned to 49907e53dc)
Solutions
- Log normalized.data to inspect the actual nesting and confirm the expected data.data envelope.
- Reload and rerun to capture fresh request URLs in case the stored one returns a partial/failed operation.
- Check the GraphQL errors path too — data.data can be null when the operation failed silently.
- If LinkedIn added envelope nesting, adjust the data?.data access path in parseThreadPages.
Example fix
// before: blind access
const data = json.data.data;
// after: safe access with diagnostics
const data = json.data?.data;
if (!data || typeof data !== 'object' || Array.isArray(data)) {
throw new CommandExecutionError('missing normalized data; keys=' + Object.keys(json.data || {}).join(','));
} Defensive patterns
Strategy: type-guard
Validate before calling
const data = json?.data?.data;
if (!data || typeof data !== 'object' || Array.isArray(data)) {
throw new Error('Normalized payload missing data.data');
} Type guard
function hasGraphQLData(json) {
const d = json?.data?.data;
return Boolean(d) && typeof d === 'object' && !Array.isArray(d);
} Try / catch
try {
const snapshot = await cli.linkedin.threadSnapshot({ url: threadUrl });
} catch (err) {
if (err.message.includes('missing normalized data')) {
// inspect json.data for null operation results; reload and retry
} else throw err;
} Prevention
- Check for GraphQL errors before reading data.data — null results often accompany them.
- Capture fresh request URLs via page reload rather than reusing stale ones.
- Verify the envelope nesting if a proxy re-wraps responses.
When it happens
Trigger: normalized.data is undefined, normalized.data.data is null/an array/a primitive — typically an operation-level GraphQL null (errors suppressed), a partially failed response, or an envelope with extra nesting from a changed endpoint.
Common situations: GraphQL returned { data: { messengerMessages: null } }-style partial failures without an errors array; the replayed queryId resolved to an operation whose result shape differs; a middle/proxy re-wrapped the JSON with an extra layer.
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 payload is missing a message coll
- 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/0a7b4c5aa3395aac.
Report an issue: GitHub.