jackwener/OpenCLI · error · ArgumentError
--video-resolution must be sd or hd
Error message
--video-resolution must be sd or hd
What it means
When rerunning a video source (sourceIsVideo), estimateAction requires videoResolution to be exactly 'sd' or 'hd' so it can index GPU_COST_MINUTES. Any other value throws this ArgumentError before any cost lookup happens.
Source
Thrown at clis/midjourney/capabilities.js:300
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(', ')}`);
}
if (operation === 'open-editor' || operation === 'cancel') return 0;
if (operation === 'rerun' && sourceIsVideo) {
if (!['sd', 'hd'].includes(videoResolution)) throw new ArgumentError('--video-resolution must be sd or hd');
if (![1, 2, 4].includes(batchSize)) throw new ArgumentError('--batch-size must be 1, 2, or 4');
return GPU_COST_MINUTES[`video${videoResolution === 'hd' ? 'Hd' : 'Sd'}${batchSize}`];
}
if (sourceUsesOmni && ['rerun', 'vary-subtle', 'vary-strong'].includes(operation)) {
return GPU_COST_MINUTES.omni;
}
if (Object.prototype.hasOwnProperty.call(ACTION_COSTS, operation)) return ACTION_COSTS[operation];
if (['animate-low', 'animate-high', 'loop-low', 'loop-high', 'extend-low', 'extend-high'].includes(operation)) {
if (!['sd', 'hd'].includes(videoResolution)) throw new ArgumentError('--video-resolution must be sd or hd');
if (![1, 2, 4].includes(batchSize)) throw new ArgumentError('--batch-size must be 1, 2, or 4');
return GPU_COST_MINUTES[`video${videoResolution === 'hd' ? 'Hd' : 'Sd'}${batchSize}`];
}
throw new ArgumentError(`No cost model is defined for action "${operation}"`);
}
export function assertActionPlan(account, operation, { videoResolution = 'sd' } = {}) {
const capabilities = planCapabilities(account);
if (videoResolution === 'hd' && !capabilities.canHdVideoView on GitHub (pinned to 49907e53dc)
Solutions
- Pass videoResolution: 'sd' or 'hd' (lowercase) when calling estimateAction
- Normalize input: String(v).trim().toLowerCase() before the call
- Fix the CLI/config default so an invalid value never reaches estimateAction
- Guard the call site: only call with sourceIsVideo=true after validating resolution
Example fix
// before
estimateAction('rerun', { sourceIsVideo: true, videoResolution: 'HD' });
// after
const v = String(opts.videoResolution || 'sd').toLowerCase();
if (v !== 'sd' && v !== 'hd') throw new Error('--video-resolution must be sd or hd');
estimateAction('rerun', { sourceIsVideo: true, videoResolution: v }); Defensive patterns
Strategy: validation
Validate before calling
const v = String(opts.videoResolution ?? 'sd').trim().toLowerCase();
if (v !== 'sd' && v !== 'hd') throw new Error(`--video-resolution must be sd or hd, got ${opts.videoResolution}`);
const minutes = estimateAction('rerun', { ...opts, videoResolution: v, sourceIsVideo: true }); Type guard
function isVideoResolution(v) {
return v === 'sd' || v === 'hd';
} Try / catch
try {
const minutes = estimateAction('rerun', { sourceIsVideo: true, videoResolution, batchSize });
} catch (err) {
if (err instanceof ArgumentError && err.message.includes('--video-resolution')) {
console.error('Use --video-resolution sd or hd');
} else throw err;
} Prevention
- Coerce resolution with trim().toLowerCase() at the CLI boundary
- Default to 'sd' when the flag is absent
- Document allowed values in --help
- Validate before calling estimateAction rather than relying on its throw
When it happens
Trigger: estimateAction('rerun', { sourceIsVideo: true, videoResolution: '4k' }) — or any value other than 'sd'/'hd', including null/undefined passed explicitly or an uppercase 'HD'.
Common situations: Users passing --video-resolution with values like 'high', '1080p', or 'hd '; config files carrying an older allowed value set; case-sensitive comparison against 'HD'.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
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/ebe6fa52457c1b95.
Report an issue: GitHub.