musistudio/claude-code-router · error · Error
duration must be an integer number of seconds.
Error message
duration must be an integer number of seconds.
What it means
Thrown by videoStart when the resolved duration is not an integer number of seconds. Providers require whole-second durations; fractional values like 4.5 fail this Number.isInteger check.
Source
Thrown at packages/core/src/media/service.ts:155
}
async imageEdit(args: Record<string, unknown>, modelInput: MediaModelInput): Promise<PublicMediaJob> {
const request: ImageEditRequest = {
aspectRatio: optionalString(args.aspect_ratio),
images: this.validateImages(args.images ?? args.image, 1, 3),
prompt: requiredPrompt(args.prompt)
};
const modelPlan = this.mediaModelPlan("image-edit", modelInput);
return this.submitAndWait("image-edit", request, modelPlan, optionalString(args.idempotency_key));
}
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}.`);View on GitHub (pinned to 99f24806c6)
Solutions
- Round to the nearest allowed integer: Math.round(duration)
- Validate duration upstream with an integer-only input field (step=1)
- Pick an integer from the protocol's allowed durations list
Example fix
// before
media.videoStart({ prompt, duration: millis / 1000 }, modelInput);
// after
media.videoStart({ prompt, duration: Math.round(millis / 1000) }, modelInput); Defensive patterns
Strategy: validation
Validate before calling
if (typeof args.duration === "number" && !Number.isInteger(args.duration)) {
args.duration = Math.round(args.duration);
} Type guard
const isIntegerDuration = (d: unknown): d is number => typeof d === "number" && Number.isInteger(d) && d > 0;
Prevention
- Use step=1 integer inputs for duration in UIs
- Round any computed duration before calling videoStart
When it happens
Trigger: Passing duration: 4.5, a computed float (e.g. from a division or unit conversion), or a numeric string parsed to a non-integer.
Common situations: Computing duration from milliseconds (ms/1000 producing 4.5); user input accepted as free-form decimals; defaulting to a fractional value from external config.
Related errors
- duration is required for ${target.protocol}.
- duration must be one of ${constraints.durations.join(", ")}
- duration must be between ${constraints.durationMinimum} and
- resolution is required for ${target.protocol}.
- resolution must be one of ${constraints.resolutions.join(",
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/0c62d1382e67ff4f.
Report an issue: GitHub.