{"record":{"id":"53bd196158ee857c","repo":"jackwener/OpenCLI","slug":"midjourney-history-endpoint-returned-a-malformed-p","errorCode":null,"errorMessage":"Midjourney history endpoint returned a malformed payload","messagePattern":"Midjourney history endpoint returned a malformed payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/utils.js","lineNumber":326,"sourceCode":"    throw new CommandExecutionError(\n      'No Midjourney generation credits remain for this billing period.',\n      `Check usage at ${MIDJOURNEY_URL}/account.`,\n    );\n  }\n}\n\nexport async function fetchHistory(page, userId, limit = 20) {\n  return (await fetchHistoryPage(page, userId, limit)).data;\n}\n\nexport async function fetchHistoryPage(page, userId, limit = 20, cursor = null) {\n  const cursorQuery = cursor ? `&cursor=${encodeURIComponent(cursor)}` : '';\n  const payload = await midjourneyJson(\n    page,\n    `/api/imagine?user_id=${encodeURIComponent(userId)}&page_size=${encodeURIComponent(limit)}${cursorQuery}`,\n  );\n  if (!payload || typeof payload !== 'object' || !Array.isArray(payload.data)) {\n    throw new CommandExecutionError('Midjourney history endpoint returned a malformed payload');\n  }\n  return {\n    data: payload.data,\n    cursor: stringOrNull(payload.cursor),\n    checkpoint: stringOrNull(payload.checkpoint),\n  };\n}\n\nexport async function fetchJobStatuses(page, jobIds) {\n  if (!Array.isArray(jobIds) || !jobIds.length) return [];\n  const payload = await midjourneyJson(page, '/api/job-status', {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: { jobIds, _frontend_source: 'opencli_adapter' },\n  });\n  if (!Array.isArray(payload)) {\n    throw new CommandExecutionError('Midjourney job-status endpoint returned a malformed payload');\n  }","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/utils.js#L308-L344","documentation":"fetchHistoryPage calls /api/imagine with user_id, page_size, and optional cursor, then validates the payload. It throws CommandExecutionError if the response is not an object with an Array 'data' field, since pagination cannot proceed without the expected rows/cursor structure.","triggerScenarios":"The history endpoint returns null, a non-object, an object without data, or data is not an array — e.g. auth interstitial JSON, API contract change, empty error body, or wrong user_id parameter causing an error envelope.","commonSituations":"Midjourney renaming or nesting the history response (e.g. data moved under results), Cloudflare challenge JSON, expired session returning an error object without data, or passing a malformed userId.","solutions":["Log the raw payload from /api/imagine to inspect the actual shape.","Re-authenticate in Chrome and retry to rule out an auth-related error envelope.","Verify the user_id passed to fetchHistoryPage matches getMidjourneyAccount's user_id.","If the API shape changed (e.g. data renamed), update the CLI's history parsing and response validation."],"exampleFix":"// before\nconst page = await fetchHistoryPage(mjPage, userId, { limit: 20 });\n// after\nconst raw = await midjourneyJson(mjPage, `/api/imagine?user_id=${userId}&page_size=20`);\nif (!raw || !Array.isArray(raw.data)) console.error('unexpected history payload:', raw);\nconst page = await fetchHistoryPage(mjPage, userId, { limit: 20 });","handlingStrategy":"type-guard","validationCode":"const payload = await midjourneyJson(page, `/api/imagine?user_id=${userId}&page_size=20`);\nif (payload == null || typeof payload !== 'object' || !Array.isArray(payload.data)) console.error('unexpected history payload', payload);","typeGuard":"function isHistoryPayload(value) {\n  return value != null && typeof value === 'object' && !Array.isArray(value) && Array.isArray(value.data);\n}","tryCatchPattern":"try {\n  const pageData = await fetchHistoryPage(page, userId, { limit: 20 });\n} catch (err) {\n  if (/history endpoint returned a malformed payload/.test(err.message)) {\n    console.error('History API shape unexpected; re-authenticate or update the CLI parser.');\n  } else throw err;\n}","preventionTips":["Validate user_id comes from a live getMidjourneyAccount call","Log raw history responses to catch API contract changes early","Re-authenticate before long history crawls","Guard pagination loops with the payload type guard before reading cursor/checkpoint"],"tags":["midjourney","schema-validation","pagination","api"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}