{"record":{"id":"7eb59d5a7d357a20","repo":"jackwener/OpenCLI","slug":"linkedin-thread-snapshot","errorCode":null,"errorMessage":"linkedin thread-snapshot","messagePattern":"linkedin thread-snapshot","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":293,"sourceCode":"    const senderUrn = normalizeWhitespace(entity['*sender'] || entity['*actor']);\n    const sender = senderUrn ? entities.get(senderUrn) : null;\n    const speaker = participantName(sender);\n    if (!speaker) {\n      throw new CommandExecutionError('LinkedIn messengerMessages payload contains a message with an unresolved sender.');\n    }\n    byMessageId.set(messageId, {\n      messageUrn: messageId,\n      speaker,\n      text: messageText(entity),\n      deliveredAt,\n    });\n  }\n\n  const messages = Array.from(byMessageId.values())\n    .sort((left, right) => left.deliveredAt - right.deliveredAt || left.messageUrn.localeCompare(right.messageUrn))\n    .map((message, index) => ({ index, ...message }));\n  if (messages.length === 0) {\n    throw new EmptyResultError('linkedin thread-snapshot', 'No messages were found in the LinkedIn thread.');\n  }\n  return { recipientNames, messages };\n}\n\ncli({\n  site: 'linkedin',\n  name: 'thread-snapshot',\n  access: 'read',\n  description: 'Load a LinkedIn messaging thread and return a structured conversation snapshot',\n  domain: LINKEDIN_DOMAIN,\n  strategy: Strategy.COOKIE,\n  browser: true,\n  args: [\n    { name: 'thread-url', required: true, help: 'Exact LinkedIn messaging thread URL to open and snapshot' },\n    { name: 'max-scrolls', type: 'number', default: 30, help: 'Maximum upward scroll attempts used to request older message pages' },\n    { name: 'json', type: 'bool', default: false, help: 'Return only JSON snapshot string in the snapshot_json field' },\n  ],\n  columns: ['thread_url', 'recipient', 'message_count', 'latest_text', 'snapshot_json'],","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L275-L311","documentation":"This is an EmptyResultError, not a CommandExecutionError: after successful parsing and deduplication, zero Message entities survived, so the thread has no snapshot-able messages. The library throws it to signal a legitimate empty result distinct from a malformed payload, letting callers handle 'nothing found' uniformly.","triggerScenarios":"All entities in `included` have $type values other than com.linkedin.messenger.Message, the container's elements list is empty, or every message was filtered out — e.g. an empty/brand-new thread, or the messages live on pages never captured because max-scrolls was too low.","commonSituations":"Snapshotting a thread with only connection requests/system content and no actual messages; setting --max-scrolls too low so older messages were never fetched; a LinkedIn schema rename of the Message $type making the filter match nothing.","solutions":["Increase --max-scrolls so pagination captures all message pages","Verify the thread actually contains messages in the LinkedIn UI before snapshotting","Update the library if the Message $type string changed; inspect included[] $type values","Handle EmptyResultError explicitly in your caller so empty threads don't crash your pipeline"],"exampleFix":"// before: too few scrolls on a long thread\nawait cliRun('linkedin thread-snapshot', { 'thread-url': url, 'max-scrolls': 2 });\n// after\nawait cliRun('linkedin thread-snapshot', { 'thread-url': url, 'max-scrolls': 30 });","handlingStrategy":"try-catch","validationCode":"// Pre-check thread has messages by inspecting captured Message entities before invoking\nconst hasMessages = pages.some(p => p.json?.included?.some(e => e?.$type === 'com.linkedin.messenger.Message'));\nif (!hasMessages) throw new EmptyResultLikeError('thread has no snapshot-able messages');","typeGuard":null,"tryCatchPattern":"try {\n  const snap = await run('linkedin thread-snapshot', { 'thread-url': url });\n} catch (err) {\n  if (err.name === 'EmptyResultError') {\n    return { thread_url: url, message_count: 0, latest_text: null, snapshot_json: null };\n  }\n  throw err;\n}","preventionTips":["Treat EmptyResultError as an expected outcome, not a bug","Raise --max-scrolls when threads are long","Confirm the thread contains real messages in the LinkedIn UI first"],"tags":["linkedin","empty-result","pagination"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}