{"record":{"id":"c50c32086a2aacc9","repo":"jackwener/OpenCLI","slug":"linkedin-messengermessages-graphql-returned-errors","errorCode":null,"errorMessage":"LinkedIn messengerMessages GraphQL returned errors.","messagePattern":"LinkedIn messengerMessages GraphQL returned errors\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/thread-snapshot.js","lineNumber":215,"sourceCode":"}\n\nfunction parseThreadPages(pages) {\n  if (!Array.isArray(pages) || pages.length === 0) {\n    throw new CommandExecutionError('LinkedIn messengerMessages API returned no pages.');\n  }\n\n  const entities = new Map();\n  const apiUrls = [];\n  for (const page of pages) {\n    if (!page || typeof page !== 'object' || Array.isArray(page) || typeof page.url !== 'string') {\n      throw new CommandExecutionError('LinkedIn messengerMessages API returned a malformed page wrapper.');\n    }\n    const normalized = page.json;\n    if (!normalized || typeof normalized !== 'object' || Array.isArray(normalized)) {\n      throw new CommandExecutionError('LinkedIn messengerMessages API returned a malformed normalized payload.');\n    }\n    if (Array.isArray(normalized.errors) && normalized.errors.length > 0) {\n      throw new CommandExecutionError('LinkedIn messengerMessages GraphQL returned errors.');\n    }\n    if (!Array.isArray(normalized.included)) {\n      throw new CommandExecutionError('LinkedIn messengerMessages payload is missing the included entity array.');\n    }\n    const data = normalized.data?.data;\n    if (!data || typeof data !== 'object' || Array.isArray(data)) {\n      throw new CommandExecutionError('LinkedIn messengerMessages payload is missing normalized data.');\n    }\n    const container = Object.entries(data).find(([key, value]) => (\n      /^messengerMessages/i.test(key)\n      && value\n      && typeof value === 'object'\n      && !Array.isArray(value)\n      && (Array.isArray(value['*elements']) || Array.isArray(value.elements))\n    ));\n    if (!container) {\n      throw new CommandExecutionError('LinkedIn messengerMessages payload is missing a message collection.');\n    }","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/thread-snapshot.js#L197-L233","documentation":"Thrown by parseThreadPages when the normalized payload contains a non-empty errors array, meaning LinkedIn's GraphQL endpoint itself reported errors for this messengerMessages query. The library treats a GraphQL error response as fatal for that page rather than emitting a partial thread snapshot.","triggerScenarios":"The replayed fetch succeeded at HTTP level (2xx) but response JSON has normalized.errors set — e.g. GraphQL-level validation errors, throttling, or a stale/unknown queryId no longer accepted server-side.","commonSituations":"LinkedIn rotated the messengerMessages queryId after a deploy so a cached URL's query is rejected; the session lacks permission for the conversation; the payload exceeded server limits; LinkedIn-side incident returning GraphQL errors while keeping 200 status.","solutions":["Read normalized.errors[0].message to identify the GraphQL failure (unknown query, throttled, access denied).","Reload the thread and rerun so discovery captures the current queryId instead of a stale one.","Retry after a backoff if errors indicate throttling; if 'query not found', update discovery to the freshly issued request URLs.","Re-authenticate if errors indicate access/permission problems."],"exampleFix":"// before: ignoring errors and parsing anyway\nconst data = json.data?.data;\n// after: check GraphQL errors first (as the library does)\nif (Array.isArray(json.errors) && json.errors.length > 0) {\n  throw new CommandExecutionError('GraphQL errors: ' + json.errors.map((e) => e.message).join('; '));\n}\nconst data = json.data?.data;","handlingStrategy":"retry","validationCode":"// Cannot be pre-validated client-side; surface errors before parsing:\nif (Array.isArray(json?.errors) && json.errors.length) {\n  console.error('GraphQL errors:', json.errors.map((e) => e.message).join('; '));\n}","typeGuard":"function hasGraphQlErrors(json) {\n  return Array.isArray(json?.errors) && json.errors.length > 0;\n}","tryCatchPattern":"try {\n  const snapshot = await cli.linkedin.threadSnapshot({ url: threadUrl });\n} catch (err) {\n  if (err.message.includes('GraphQL returned errors')) {\n    // reload to refresh queryId, back off if throttled, retry with exponential backoff\n  } else throw err;\n}","preventionTips":["Reload the thread before running so a current (non-rotated) queryId is captured.","Add retry with exponential backoff for throttling-style GraphQL errors.","Re-authenticate when error messages indicate permission failures.","Monitor LinkedIn deploys — queryId rotation after releases commonly triggers this."],"tags":["linkedin","graphql","api-error","scraping"],"backgroundTag":"graphql-errors","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}