jackwener/OpenCLI · error · CommandExecutionError
LinkedIn messengerMessages payload contains a message withou
Error message
LinkedIn messengerMessages payload contains a message without an id.
What it means
For every com.linkedin.messenger.Message entity, parseThreadPages derives an id from entityUrn || backendUrn || originToken. It throws when all three are empty/whitespace, because messages must be keyed by a stable id for deduplication and sorting.
Source
Thrown at clis/linkedin/thread-snapshot.js:269
}
const participants = Array.from(entities.values()).filter(
(entity) => entity.$type === 'com.linkedin.messenger.MessagingParticipant',
);
const recipientNames = Array.from(new Set(participants
.filter((participant) => participant.hostIdentityUrn !== ownerUrn)
.map(participantName)
.filter(Boolean)));
if (recipientNames.length === 0) {
throw new CommandExecutionError('LinkedIn messengerMessages payload is missing the counterparty participant.');
}
const byMessageId = new Map();
for (const entity of entities.values()) {
if (entity.$type !== 'com.linkedin.messenger.Message') continue;
const messageId = normalizeWhitespace(entity.entityUrn || entity.backendUrn || entity.originToken);
if (!messageId) {
throw new CommandExecutionError('LinkedIn messengerMessages payload contains a message without an id.');
}
const deliveredAt = Number(entity.deliveredAt);
if (!Number.isFinite(deliveredAt) || deliveredAt <= 0) {
throw new CommandExecutionError('LinkedIn messengerMessages payload contains a message without a valid timestamp.');
}
const senderUrn = normalizeWhitespace(entity['*sender'] || entity['*actor']);
const sender = senderUrn ? entities.get(senderUrn) : null;
const speaker = participantName(sender);
if (!speaker) {
throw new CommandExecutionError('LinkedIn messengerMessages payload contains a message with an unresolved sender.');
}
byMessageId.set(messageId, {
messageUrn: messageId,
speaker,
text: messageText(entity),
deliveredAt,
});
}View on GitHub (pinned to 49907e53dc)
Solutions
- Update the library to match the current Message entity id field names
- Re-capture the thread — partial hydration is often transient
- Log and inspect the offending entity's keys to find the new id field, and extend the fallback chain
- If building fixtures, ensure every Message entity carries at least one of entityUrn/backendUrn/originToken
Example fix
// before const messageId = normalizeWhitespace(entity.entityUrn || entity.backendUrn || entity.originToken); // after: extend fallback to new schema field const messageId = normalizeWhitespace(entity.entityUrn || entity.backendUrn || entity.originToken || entity.messageUrn);
Defensive patterns
Strategy: type-guard
Validate before calling
function messageHasId(entity) {
return !!(entity.entityUrn || entity.backendUrn || entity.originToken);
}
const bad = payloads.flatMap(p => p.included).filter(e => e?.$type === 'com.linkedin.messenger.Message' && !messageHasId(e));
if (bad.length) throw new Error('Message entities missing ids: ' + bad.length); Type guard
const hasMessageId = (e) => typeof (e.entityUrn || e.backendUrn || e.originToken) === 'string' && !!(e.entityUrn || e.backendUrn || e.originToken).trim();
Try / catch
try {
const snap = await run('linkedin thread-snapshot', { 'thread-url': url });
} catch (err) {
if (String(err.message).includes('message without an id')) {
// schema drift: log entity keys and upgrade parser
} else throw err;
} Prevention
- Inspect captured Message entities for id fields after LinkedIn schema updates
- Extend the id fallback chain when new id fields appear
- Validate fixtures contain entityUrn/backendUrn/originToken before replay
When it happens
Trigger: A Message entity in `included` has none of entityUrn, backendUrn, or originToken set — e.g. LinkedIn schema change renaming the id field, or a partially hydrated entity from a truncated page.
Common situations: Outdated parser after a LinkedIn GraphQL schema update; stub/placeholder entities returned in some response variants; manually recorded fixtures missing id fields.
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 people search returned malformed extraction payload
- LinkedIn cookie lookup returned malformed payload
- LinkedIn people search returned malformed extraction payload
- Sales Navigator messaging thread row missing id
- LinkedIn sent invitations returned a malformed extraction pa
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7766971b69ff7a11.
Report an issue: GitHub.