musistudio/claude-code-router · error · Error
resolution must be one of
Error message
resolution must be one of ${constraints.resolutions.join(", ")} for ${target.protocol}. What it means
Thrown when the supplied resolution is not in the protocol's allowed resolutions list. The message lists the accepted values so the fix is usually immediate.
Solutions
- Use one of the exact values listed in the error message
- Populate your picker from videoGenerationConstraints(protocol).resolutions
- Normalize/case-fold user input against the allowlist before calling
Example fix
// before
media.videoStart({ prompt, resolution: "1920x1080" }, modelInput);
// after
media.videoStart({ prompt, resolution: "1080p" }, modelInput); Defensive patterns
Strategy: validation
Validate before calling
const c = videoGenerationConstraints(protocol);
if (!c.resolutions.includes(resolution)) {
throw new Error(`Allowed: ${c.resolutions.join(", ")}`);
} Type guard
const isAllowedResolution = (r: string, c: VideoConstraints): boolean => c.resolutions.includes(r);
Prevention
- Use exact provider vocabulary (e.g. "1080p")
- Populate selects from constraints.resolutions
When it happens
Trigger: Passing e.g. resolution: "4k" for a protocol whose constraints.resolutions only includes ["480p","720p","1080p"].
Common situations: Hardcoded resolution strings from other providers ("1920x1080" vs "1080p"); user free-text resolution input; uppercase/case-mismatched values.
Related errors
- aspect_ratio must be one of
- duration must be one of
- aspect_ratio is required for
- duration is required for
- duration must be an integer number of seconds.
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/4b8586c8f9b47e6e.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/media/service.ts:166
videoStart(args: Record<string, unknown>, modelInput: MediaModelInput): PublicMediaJob {
const modelPlan = this.mediaModelPlan("video-generate", modelInput);
const target = resolveProviderMediaTarget(this.requireConfig(), modelPlan.modelSelector, "video-generate");
const constraints = videoGenerationConstraints(target.protocol);
const durationValue = numberValue(args.duration) ?? constraints.defaultDuration;
if (durationValue === undefined) throw new Error(`duration is required for ${target.protocol}.`);
if (!Number.isInteger(durationValue)) throw new Error("duration must be an integer number of seconds.");
if (constraints.durations && !constraints.durations.includes(durationValue)) {
throw new Error(`duration must be one of ${constraints.durations.join(", ")} seconds for ${target.protocol}.`);
}
if (constraints.durationMinimum !== undefined && constraints.durationMaximum !== undefined &&
(durationValue < constraints.durationMinimum || durationValue > constraints.durationMaximum)) {
throw new Error(`duration must be between ${constraints.durationMinimum} and ${constraints.durationMaximum} seconds for ${target.protocol}.`);
}
const resolution = optionalString(args.resolution) ?? constraints.defaultResolution;
if (!resolution) throw new Error(`resolution is required for ${target.protocol}.`);
if (!constraints.resolutions.includes(resolution)) {
throw new Error(`resolution must be one of ${constraints.resolutions.join(", ")} for ${target.protocol}.`);
}
const aspectRatio = optionalString(args.aspect_ratio);
if (constraints.requiredParameters.includes("aspect_ratio") && !aspectRatio) {
throw new Error(`aspect_ratio is required for ${target.protocol}.`);
}
if (aspectRatio && !constraints.aspectRatios.includes(aspectRatio)) {
throw new Error(`aspect_ratio must be one of ${constraints.aspectRatios.join(", ")} for ${target.protocol}.`);
}
const request: VideoGenerateRequest = {
aspectRatio,
duration: durationValue,
images: args.images === undefined && args.image === undefined ? [] : this.validateImages(args.images ?? args.image, 1, 7),
prompt: requiredPrompt(args.prompt),
resolution
};
const job = this.submit("video-generate", request, modelPlan, optionalString(args.idempotency_key));
return this.publicJob(job);
}View on GitHub (pinned to 99f24806c6)