jackwener/OpenCLI · error · CommandExecutionError
Sales Navigator messaging threads API returned malformed pay
Error message
Sales Navigator messaging threads API returned malformed payload
What it means
This CommandExecutionError is thrown by parseSalesnavThreads when the Sales Navigator messaging threads API response is not an object with an elements array. It guards against HTML error pages, auth redirects, or schema changes reaching the row parser.
Source
Thrown at clis/linkedin/salesnav-inbox.js:61
const resolution = thread?.participantsResolutionResults || {};
const participants = Array.isArray(thread?.participants) ? thread.participants : Object.keys(resolution);
return participants.map((urn) => resolution[urn] || { entityUrn: urn }).filter(Boolean);
}
function isSelfParticipant(profile) {
const degree = String(profile?.degree ?? '').trim();
return degree === '0';
}
function otherParticipantName(thread) {
const participants = getThreadParticipants(thread);
const other = participants.find((p) => !isSelfParticipant(p)) || participants[0];
return normalizeWhitespace(other?.fullName || [other?.firstName, other?.lastName].filter(Boolean).join(' '));
}
function parseSalesnavThreads(json) {
if (!json || typeof json !== 'object' || !Array.isArray(json.elements)) {
throw new CommandExecutionError('Sales Navigator messaging threads API returned malformed payload');
}
return json.elements.map((thread) => {
if (!thread || typeof thread !== 'object') {
throw new CommandExecutionError('Sales Navigator messaging threads API returned malformed thread row');
}
const messages = Array.isArray(thread?.messages) ? thread.messages : [];
const lastMessage = messages[0] || {};
const deliveredAt = Number(lastMessage.deliveredAt || thread?.nextPageStartsAt || 0);
const threadId = normalizeWhitespace(thread?.id || '');
if (!threadId) {
throw new CommandExecutionError('Sales Navigator messaging thread row missing id');
}
return {
thread_id: threadId,
thread_url: salesnavThreadUrl(threadId),
person_name: otherParticipantName(thread),
last_message_snippet: normalizeWhitespace(lastMessage.body || lastMessage.subject || '').slice(0, 300),
last_activity_time: deliveredAt ? new Date(deliveredAt).toISOString() : '',View on GitHub (pinned to 49907e53dc)
Solutions
- Re-authenticate / refresh the LinkedIn session and retry
- Verify the CSRF token is fresh (getCsrf) before calling the API
- Update the library if Sales Navigator changed the threads response schema
- Log the raw response body to confirm what the endpoint actually returned
Example fix
// before
const json = JSON.parse(rawText);
parseSalesnavThreads(json);
// after
const json = JSON.parse(rawText);
if (!json?.elements) throw new Error('threads payload missing elements: ' + rawText.slice(0, 200));
parseSalesnavThreads(json); Defensive patterns
Strategy: validation
Validate before calling
const json = await fetchPageJson(url);
if (!json || typeof json !== 'object' || !Array.isArray(json.elements)) {
throw new Error('Threads payload malformed; raw: ' + JSON.stringify(json).slice(0, 200));
} Type guard
function isThreadsPayload(v) {
return !!v && typeof v === 'object' && Array.isArray(v.elements);
} Try / catch
try {
const rows = await fetchInboxRows(page);
} catch (e) {
if (String(e.message).includes('malformed payload')) {
await relogin(page); // often a stale session
return fetchInboxRows(page);
}
throw e;
} Prevention
- Refresh the CSRF token before each inbox fetch
- Capture raw response bodies on failure for diagnosis
- Pin/monitor Sales Nav API schema changes
- Retry once on malformed payloads before failing the job
When it happens
Trigger: Calling fetchInboxRows/pageRows when the Sales Nav messaging endpoint returns JSON lacking json.elements — e.g. a login redirect body, a rate-limit JSON error, or a LinkedIn API schema change renaming/moving elements.
Common situations: Expired Sales Navigator session returning a non-thread payload; CSRF token stale so the API answers with an error envelope; LinkedIn changed the messaging threads response shape; hitting the wrong endpoint URL.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${label} returned an unexpected response
- Sales Navigator messaging threads API returned malformed thr
- ${label} failed
- ${label} returned malformed response
- Sales Navigator lead search API returned malformed payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9463da333612f2d7.
Report an issue: GitHub.