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

  1. Round to the nearest allowed integer: Math.round(duration)
  2. Validate duration upstream with an integer-only input field (step=1)
  3. 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

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


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/0c62d1382e67ff4f. Report an issue: GitHub.