{"record":{"id":"b23a0286e1816f07","repo":"jackwener/OpenCLI","slug":"linkedin-messengermessages-api-returned-an-unexpec","errorCode":null,"errorMessage":"LinkedIn messengerMessages API returned an unexpected response: ${fetched?.error || 'no data'}","messagePattern":"LinkedIn messengerMessages API returned an unexpected response: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":359,"sourceCode":"\n    const actualUrl = canonicalizeLinkedInThreadUrl(discovery.url || '');\n    if (threadUrl && actualUrl && threadUrl !== actualUrl) {\n      throw new CommandExecutionError('LinkedIn thread-snapshot blocked: thread_url_mismatch', `Expected ${threadUrl}; actual ${actualUrl}`);\n    }\n    if (maxScrolls >= 4 && discovery.scrollAttempts >= maxScrolls && discovery.scrollStable === false) {\n      throw new CommandExecutionError('LinkedIn thread history did not stabilize before --max-scrolls; refusing to return a partial snapshot.');\n    }\n\n    const apiUrls = validateThreadApiUrls(discovery.apiUrls, threadUrl);\n    const csrf = await requireLinkedInCookie(page, 'LinkedIn thread-snapshot');\n    const fetched = unwrapEvaluateResult(\n      await page.evaluate(buildFetchThreadPagesScript(apiUrls, csrf)),\n    );\n    if (fetched?.authRequired) {\n      throw new AuthRequiredError(LINKEDIN_DOMAIN, `LinkedIn messengerMessages API authentication failed: ${fetched.error}`);\n    }\n    if (!fetched || fetched.error || !Array.isArray(fetched.pages)) {\n      throw new CommandExecutionError(`LinkedIn messengerMessages API returned an unexpected response: ${fetched?.error || 'no data'}`);\n    }\n\n    const parsed = parseThreadPages(fetched.pages);\n    const recipient = parsed.recipientNames.join(', ');\n    const latestMessageText = parsed.messages[parsed.messages.length - 1]?.text || '';\n    const normalized = {\n      url: actualUrl || threadUrl,\n      title: normalizeWhitespace(discovery.title),\n      headerNames: parsed.recipientNames,\n      latestMessageText,\n      messages: parsed.messages,\n      messageCount: parsed.messages.length,\n      authRequired: false,\n      extractedAt: new Date().toISOString(),\n      maxScrolls,\n      source: 'linkedin-messengerMessages',\n    };\n","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L341-L377","documentation":"The in-page fetch of the messengerMessages API returned a response the parser cannot use: no data, an error field, or a missing/non-array pages property. This is a contract violation of the expected {pages: [...]} response shape, thrown as CommandExecutionError with the underlying error or 'no data'.","triggerScenarios":"messengerMessages API returning an HTML error page, a JSON body without a pages array (LinkedIn schema change), an empty/blocked response, or fetched being null after unwrapEvaluateResult.","commonSituations":"LinkedIn silently changing the messengerMessages response schema; thread deleted mid-fetch returning an error payload; network failure or anti-bot interstitial replacing the API response; LinkedIn CDN serving an error JSON.","solutions":["Read the ${fetched?.error} detail in the message to identify the underlying API failure and address it","Retry the command after confirming the thread loads in the normal LinkedIn web UI","Refresh the page/session (cookies, CSRF token) and retry, ruling out a transient block","If it persists after a confirmed UI-side schema change, update the CLI to the latest version or file an issue — the parse contract may be stale"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Confirm the thread renders in the normal UI before invoking\nawait page.goto(threadUrl); await page.wait(10);\nconst ok = await page.evaluate(() => !!document.querySelector('.msg-thread, [data-view-name=\"thread\"]'));\nif (!ok) throw new Error('Thread not rendered; fix session/page before snapshot');","typeGuard":null,"tryCatchPattern":"try {\n  await threadSnapshot({ threadUrl });\n} catch (e) {\n  if (String(e.message).includes('unexpected response')) {\n    await page.reload(); await page.wait(5);\n    return threadSnapshot({ threadUrl }); // single retry after refresh\n  } else throw e;\n}","preventionTips":["Keep the CLI updated against LinkedIn API schema changes","Confirm the thread opens in the normal web UI before snapshotting","Retry after page refresh before investigating deeper","Persist the underlying error detail from the message for bug reports"],"tags":["linkedin","api-schema","unexpected-response","browser-automation"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}