{"record":{"id":"8ca418d8e37236a2","repo":"jackwener/OpenCLI","slug":"midjourney-api-request-failed-message","errorCode":null,"errorMessage":"Midjourney API request failed: ${message}","messagePattern":"Midjourney API request failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/utils.js","lineNumber":284,"sourceCode":"  return path.resolve(expanded);\n}\n\nfunction errorMessage(error) {\n  return error instanceof Error ? error.message : String(error);\n}\n\nasync 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.',","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/utils.js#L266-L302","documentation":"midjourneyJson rethrows any non-auth HTTP failure as CommandExecutionError('Midjourney API request failed: <message>'). This is the generic transport/request failure path: network errors, 5xx responses, timeouts, DNS failures, or non-401/403 status codes that do not match the auth regex.","triggerScenarios":"The underlying fetch/request inside midjourneyJson throws with a message not matching the auth regex — e.g. HTTP 429, 500, 502, connection reset, timeout, TLS error.","commonSituations":"Midjourney API outages or Cloudflare blocks, rate limiting (HTTP 429) after bursts of requests, corporate proxies intercepting TLS, or transient network drops.","solutions":["Inspect the wrapped message for the underlying status or cause (e.g. 429 vs 500).","Retry with exponential backoff for 429/5xx errors after waiting.","Check Midjourney status / try the endpoint in the logged-in browser to confirm it is not an outage.","Verify proxy/TLS settings if the message indicates connection or certificate errors."],"exampleFix":"// before\nconst data = await midjourneyJson(page, url);\n// after\nconst data = await withRetry(() => midjourneyJson(page, url), { retries: 3, backoff: 'exponential' });","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isTransientHttpError(err) {\n  return /HTTP\\s+(429|5\\d\\d)|timeout|ECONNRESET|ECONNREFUSED|socket/i.test(String(err?.message));\n}","tryCatchPattern":"try {\n  const data = await midjourneyJson(page, url);\n} catch (err) {\n  if (/Midjourney API request failed/.test(err.message)) {\n    if (isTransientHttpError(err)) await sleep(backoff(attempt++)); // retry\n    else throw err;\n  } else throw err;\n}","preventionTips":["Implement exponential backoff for 429/5xx responses","Rate-limit outgoing Midjourney calls to stay under thresholds","Watch Midjourney status pages for outages before batch runs","Log the underlying message embedded in the wrapper error for diagnosis"],"tags":["midjourney","network","http-error","api"],"backgroundTag":"http-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}