jackwener/OpenCLI · error · ArgumentError
Estimated GPU cost ${estimatedMinutes} minutes exceeds --max
Error message
Estimated GPU cost ${estimatedMinutes} minutes exceeds --max-minutes ${max} What it means
assertBudget enforces a user-supplied ceiling (--max-minutes, default 2) on the estimated GPU minutes for a generation. This ArgumentError is thrown when estimatedMinutes (per-job cost x repeat, adjusted for turbo/hd/omni/draft/relax) exceeds that ceiling, so a job that would be unexpectedly expensive is blocked before submission.
Source
Thrown at clis/midjourney/capabilities.js:279
if (speed === 'relax') perJobMinutes = 0;
const estimatedMinutes = Number((perJobMinutes * repeat).toFixed(2));
return {
requestedModel,
effectiveModel: selectedModel,
routingReason,
resolution,
speed,
repeat,
estimatedMinutes,
};
}
export function assertBudget(account, estimatedMinutes, maxMinutes, reserveMinutes, creditsToMinutes) {
const max = normalizeNonNegativeNumber(maxMinutes, 2, '--max-minutes');
const reserve = normalizeNonNegativeNumber(reserveMinutes, 0, '--reserve-minutes');
if (estimatedMinutes > max) {
throw new ArgumentError(`Estimated GPU cost ${estimatedMinutes} minutes exceeds --max-minutes ${max}`);
}
const remainingCredits = Number(account?.total_credits ?? account?.credits_total);
const remainingMinutes = creditsToMinutes(remainingCredits);
if (Number.isFinite(remainingMinutes) && remainingMinutes - estimatedMinutes < reserve) {
throw new CommandExecutionError(
`Midjourney budget guard would leave ${Number((remainingMinutes - estimatedMinutes).toFixed(2))} minutes, below the ${reserve}-minute reserve`,
);
}
return { maxMinutes: max, reserveMinutes: reserve, remainingMinutes };
}
export function estimateAction(
operation,
{ videoResolution = 'sd', batchSize = 1, sourceIsVideo = false, sourceUsesOmni = false } = {},
) {
if (!ACTION_CHOICES.includes(operation)) {
throw new ArgumentError(`operation must be one of: ${ACTION_CHOICES.join(', ')}`);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Raise --max-minutes to at least the estimated cost shown in the error (e.g. --max-minutes 8).
- Reduce repeat count, or drop --hd/--turbo/--oref to lower the per-job GPU cost.
- Use relax speed (0 GPU minutes) if latency is acceptable and the estimate must fit a tiny budget.
- Call the plan/estimate API first and set --max-minutes from estimatedMinutes programmatically.
Example fix
// before midjourney generate 'a cat --hd' --repeat 4 // default --max-minutes 2 // after midjourney generate 'a cat --hd' --repeat 4 --max-minutes 8
Defensive patterns
Strategy: validation
Validate before calling
const planResult = await midjourney.plan({ prompt, repeat, resolution, speed });
const maxMinutes = Number(process.env.MAX_MINUTES ?? 2);
if (planResult.estimatedMinutes > maxMinutes) {
throw new Error(`estimate ${planResult.estimatedMinutes} min exceeds budget ${maxMinutes}; raise --max-minutes or reduce repeat`);
} Type guard
function fitsBudget(planResult, maxMinutes) {
return typeof planResult?.estimatedMinutes === 'number' && planResult.estimatedMinutes <= maxMinutes;
} Try / catch
try {
return await generate(args);
} catch (err) {
if (err instanceof ArgumentError && err.message.startsWith('Estimated GPU cost')) {
const est = Number(err.message.match(/cost ([\d.]+)/)[1]);
const max = Number(err.message.match(/--max-minutes ([\d.]+)/)[1]);
return generate({ ...args, maxMinutes: Math.ceil(est) });
}
throw err;
} Prevention
- Call the plan/estimate API before generating and set --max-minutes from the estimate.
- Remember turbo doubles, hd/omni raise per-job cost; re-budget when changing these flags.
- Don't leave --max-minutes at the default 2 when running repeat batches.
- Set --max-minutes explicitly in CI/scripts rather than relying on defaults.
When it happens
Trigger: Calling the generate flow with estimatedMinutes > maxMinutes: e.g. --repeat 4 with hd resolution (or turbo, or omni reference) while --max-minutes is left at the default 2, or passing a non-negative but too-small --max-minutes.
Common situations: Forgetting to raise --max-minutes when scaling up repeat or switching to HD/Turbo/Omni; keeping the default 2-minute budget after moving from relax to fast jobs; batch scripts with fixed budgets hitting costlier models.
Related errors
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
- archive search limit must be <= 100
- archive search query must not be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a286724e11bd84a0.
Report an issue: GitHub.