{"record":{"id":"ec917d056f1c0d50","repo":"jackwener/OpenCLI","slug":"linkedin-did-not-issue-a-messengermessages-api-req","errorCode":null,"errorMessage":"LinkedIn did not issue a messengerMessages API request for this thread.","messagePattern":"LinkedIn did not issue a messengerMessages API request for this thread\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":176,"sourceCode":"    || message?.subject\n    || '',\n  );\n}\n\nfunction ownerUrnFromApiUrls(apiUrls) {\n  for (const url of apiUrls) {\n    let decoded = url;\n    try { decoded = decodeURIComponent(url); } catch {}\n    const match = decoded.match(/conversationUrn:urn:li:msg_conversation:\\((urn:li:fsd_profile:[^,)]+)/i);\n    if (match) return match[1];\n  }\n  return '';\n}\n\nfunction validateThreadApiUrls(apiUrls, threadUrl) {\n  const threadId = new URL(threadUrl).pathname.match(/^\\/messaging\\/thread\\/([^/]+)\\/?$/i)?.[1] || '';\n  if (!Array.isArray(apiUrls) || apiUrls.length === 0) {\n    throw new CommandExecutionError('LinkedIn did not issue a messengerMessages API request for this thread.');\n  }\n  for (const value of apiUrls) {\n    let url;\n    try {\n      url = new URL(value);\n    } catch {\n      throw new CommandExecutionError('LinkedIn messengerMessages discovery returned an invalid URL.');\n    }\n    let decoded = value;\n    try { decoded = decodeURIComponent(value); } catch {}\n    if (url.protocol !== 'https:'\n      || url.hostname !== LINKEDIN_DOMAIN\n      || url.pathname !== '/voyager/api/voyagerMessagingGraphQL/graphql'\n      || !/^messengerMessages\\.[a-f0-9]+$/i.test(url.searchParams.get('queryId') || '')\n      || !threadId\n      || !decoded.includes(threadId)) {\n      throw new CommandExecutionError('LinkedIn messengerMessages discovery returned an unsafe or mismatched URL.');\n    }","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L158-L194","documentation":"This error is thrown by validateThreadApiUrls when the browser-side discovery script found zero messengerMessages API requests in the page's performance resource entries. The CLI scrapes LinkedIn messaging threads by replaying the exact voyager GraphQL requests the web app made; without at least one captured URL there is nothing to fetch or parse. It signals that the thread page never issued (or the script failed to observe) a messengerMessages request.","triggerScenarios":"performance.getEntriesByType('resource') contains no URL matching /voyager/api/voyagerMessagingGraphQL/graphql with queryId=messengerMessages.<hex>, or every match was skipped because it did not decode-include the threadId. validateThreadApiUrls then receives an empty/non-array apiUrls list.","commonSituations":"Developer navigated to a wrong or non-thread URL; the messaging list page was open but the thread never loaded; LinkedIn changed its API endpoints or queryId format; a hardened browser/extension cleared or restricted the performance buffer; the thread view was server-cached so no new request fired during the scroll window.","solutions":["Verify the input URL is an exact https://www.linkedin.com/messaging/thread/<id>/ URL and that the browser actually navigated to it before running the command.","Increase --max-scrolls so the discovery script scrolls longer and gives the lazy-loaded thread time to fire messengerMessages requests.","Reload the thread page and rerun; manually open devtools Network and confirm messengerMessages requests appear when the thread loads.","Check for LinkedIn UI/API changes (new endpoint path or queryId pattern) and update the discovery regexes in buildThreadApiDiscoveryScript."],"exampleFix":"// before: running against the messaging inbox\nawait run(['linkedin', 'thread-snapshot', '--url', 'https://www.linkedin.com/messaging/']);\n// after: exact thread URL\nawait run(['linkedin', 'thread-snapshot', '--url', 'https://www.linkedin.com/messaging/thread/2-MTM0NjU0/']);","handlingStrategy":"validation","validationCode":"const m = threadUrl.match(/^\\/messaging\\/thread\\/([^/]+)\\/?$/i);\nif (!m) throw new Error('Provide an exact https://www.linkedin.com/messaging/thread/<id>/ URL before running thread-snapshot.');","typeGuard":"function isThreadUrl(u) {\n  try { return /^\\/messaging\\/thread\\/[^/]+\\/?$/i.test(new URL(u).pathname); }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  const snapshot = await cli.linkedin.threadSnapshot({ url: threadUrl });\n} catch (err) {\n  if (err.message.includes('did not issue a messengerMessages API request')) {\n    // navigate to the thread, reload the page, retry with higher --max-scrolls\n  } else throw err;\n}","preventionTips":["Always pass the exact thread URL copied from the browser address bar while the thread is open.","Reload the thread page immediately before running the command so API requests are freshly issued.","Increase --max-scrolls for long threads so lazy-loaded requests have time to fire.","Avoid browser profiles with extensions that strip resource timing entries."],"tags":["linkedin","api-discovery","scraping","empty-result"],"backgroundTag":"api-resource-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}