{"record":{"id":"d9d66e2f0c09d3b6","repo":"jackwener/OpenCLI","slug":"no-midjourney-generation-credits-remain-for-this-b","errorCode":null,"errorMessage":"No Midjourney generation credits remain for this billing period.","messagePattern":"No Midjourney generation credits remain for this billing period\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/utils.js","lineNumber":308,"sourceCode":"  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.',\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');","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/utils.js#L290-L326","documentation":"assertGenerationEntitlement computes remaining credits from total_credits ?? credits_total and throws CommandExecutionError when no credits remain and abilities.can_relax is falsy. It prevents wasting API calls on jobs that would be rejected for exhausted fast-generation quota.","triggerScenarios":"Number(account.total_credits ?? account.credits_total ?? 0) is not > 0 AND account.abilities?.can_relax is not truthy — fast hours fully consumed with no relax-mode fallback available on the plan.","commonSituations":"Heavy usage drained fast GPU hours before the monthly reset, basic plan without relax mode, or a plan change resetting credit fields mid-cycle.","solutions":["Wait for the billing period to reset fast hours, or subscribe to a higher tier.","Enable relax mode if the plan supports it (can_relax) to keep generating at lower priority.","Check usage at midjourney.com/account to confirm remaining credits.","If credits are visibly remaining but the error fires, the CLI's credit field names may be stale — update the library."],"exampleFix":"// before\nawait assertGenerationEntitlement(account); // throws when fast hours gone\n// after\nconst remaining = Number(account.total_credits ?? account.credits_total ?? 0);\nif (remaining <= 0 && account.abilities?.can_relax) {\n  await submitImagine(prompt, { mode: 'relax' }); // use relax instead\n} else {\n  await assertGenerationEntitlement(account);\n}","handlingStrategy":"fallback","validationCode":"const account = await getMidjourneyAccount(page);\nconst remaining = Number(account.total_credits ?? account.credits_total ?? 0);\nconst canRelax = Boolean(account.abilities?.can_relax);\nif (!(remaining > 0) && !canRelax) console.error('No fast credits and no relax mode — wait for reset or upgrade.');","typeGuard":"function hasGenerationBudget(account) {\n  const remaining = Number(account?.total_credits ?? account?.credits_total ?? 0);\n  return remaining > 0 || Boolean(account?.abilities?.can_relax);\n}","tryCatchPattern":"try {\n  assertGenerationEntitlement(account);\n} catch (err) {\n  if (/No Midjourney generation credits remain/.test(err.message)) {\n    console.error('Fast hours exhausted; wait for reset or enable relax mode.');\n  } else throw err;\n}","preventionTips":["Check credit balance before submitting jobs","Use relax mode proactively when fast hours run low","Schedule heavy batches early in the billing cycle","Track usage at midjourney.com/account during long runs"],"tags":["midjourney","credits","quota","subscription"],"backgroundTag":"quota-exceeded","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}