jackwener/OpenCLI · error · CommandExecutionError
LinkedIn messengerMessages API returned a malformed normaliz
Error message
LinkedIn messengerMessages API returned a malformed normalized payload.
What it means
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.
Source
Thrown at clis/linkedin/thread-snapshot.js:212
}
}
return apiUrls;
}
function parseThreadPages(pages) {
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))
));View on GitHub (pinned to 49907e53dc)
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).
Example fix
// before: storing raw text
pages.push({ url, json: await response.text() });
// after: parse JSON like the library does
pages.push({ url, json: await response.json() }); Defensive patterns
Strategy: type-guard
Validate before calling
const ok = pages.every((p) => p.json && typeof p.json === 'object' && !Array.isArray(p.json));
if (!ok) throw new Error('page.json must be a normalized JSON object'); Type guard
function isNormalizedObject(v) {
return Boolean(v) && typeof v === 'object' && !Array.isArray(v);
} Try / catch
try {
const snapshot = await cli.linkedin.threadSnapshot({ url: threadUrl });
} catch (err) {
if (err.message.includes('malformed normalized payload')) {
// retry with the normalized vendor accept header; inspect for auth walls/rate limits
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- LinkedIn messengerMessages payload is missing the included e
- 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/987a0817e5dc9d53.
Report an issue: GitHub.