{"record":{"id":"0a09878ccd90437d","repo":"jackwener/OpenCLI","slug":"midjourney-subscription-endpoint-returned-a-malfor","errorCode":null,"errorMessage":"Midjourney subscription endpoint returned a malformed payload","messagePattern":"Midjourney subscription endpoint returned a malformed payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/utils.js","lineNumber":291,"sourceCode":"async function midjourneyJson(page, endpoint, options = {}) {\n  try {\n    return await page.fetchJson(endpoint, {\n      ...options,\n      headers: { ...CSRF_HEADERS, ...(options.headers || {}) },\n    });\n  } catch (error) {\n    const message = errorMessage(error);\n    if (/HTTP\\s+(401|403)|unauthori[sz]ed|login|sign in/i.test(message)) {\n      throw new AuthRequiredError(MIDJOURNEY_DOMAIN, 'Log into Midjourney in Chrome, then retry.');\n    }\n    throw new CommandExecutionError(`Midjourney API request failed: ${message}`);\n  }\n}\n\nexport async function getMidjourneyAccount(page) {\n  const account = await midjourneyJson(page, '/api/subscriptions-check');\n  if (!account || typeof account !== 'object' || Array.isArray(account)) {\n    throw new CommandExecutionError('Midjourney subscription endpoint returned a malformed payload');\n  }\n  if (!account.user_id) {\n    throw new AuthRequiredError(MIDJOURNEY_DOMAIN, 'Log into Midjourney in Chrome, then retry.');\n  }\n  return account;\n}\n\nexport function assertGenerationEntitlement(account) {\n  if (account.status !== 'active' || !account.plan?.type) {\n    throw new CommandExecutionError(\n      'Midjourney generation requires an active subscription.',\n      `Check the account at ${MIDJOURNEY_URL}/account.`,\n    );\n  }\n  const remaining = Number(account.total_credits ?? account.credits_total ?? 0);\n  if (!(remaining > 0) && !account.abilities?.can_relax) {\n    throw new CommandExecutionError(\n      'No Midjourney generation credits remain for this billing period.',","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/utils.js#L273-L309","documentation":"getMidjourneyAccount validates the response of GET /api/subscriptions-check and throws CommandExecutionError if the payload is not a plain object (null, array, or non-object). The endpoint responded but returned data the CLI cannot interpret as an account record, so it aborts rather than dereferencing undefined fields.","triggerScenarios":"midjourneyJson(page, '/api/subscriptions-check') resolves to null, an Array, or a primitive — e.g. the endpoint returns an HTML login interstitial parsed oddly, an empty body, or an error JSON lacking the expected shape.","commonSituations":"Midjourney API contract changes, Cloudflare challenge pages returned as non-JSON, partially authenticated sessions returning empty payloads, or hitting the wrong endpoint during API version drift.","solutions":["Log the raw response body of /api/subscriptions-check to see what was actually returned.","Re-authenticate in Chrome and retry — challenge pages often cause malformed payloads.","Check for Midjourney API changes and update the CLI's expected response shape.","Retry after a delay if Cloudflare was throttling the request."],"exampleFix":"// before\nconst account = await getMidjourneyAccount(page);\n// after\nconst raw = await midjourneyJson(page, '/api/subscriptions-check');\nconsole.debug('payload', raw);\nconst account = await getMidjourneyAccount(page);","handlingStrategy":"type-guard","validationCode":"const raw = await midjourneyJson(page, '/api/subscriptions-check');\nif (raw == null || typeof raw !== 'object' || Array.isArray(raw)) console.error('unexpected subscriptions-check payload', raw);","typeGuard":"function isAccountPayload(value) {\n  return value != null && typeof value === 'object' && !Array.isArray(value);\n}","tryCatchPattern":"try {\n  const account = await getMidjourneyAccount(page);\n} catch (err) {\n  if (/malformed payload/.test(err.message)) {\n    console.error('subscriptions-check returned unexpected data; re-authenticate and retry.');\n  } else throw err;\n}","preventionTips":["Log raw endpoint payloads when integrating against Midjourney","Re-authenticate when payloads look like challenge/interstitial responses","Pin and update the CLI when Midjourney changes the API contract","Handle Cloudflare challenges before API calls"],"tags":["midjourney","schema-validation","api"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}