musistudio/claude-code-router · error · Error

duration is required for

Error message

duration is required for ${target.protocol}.

What it means

Thrown by videoStart when no duration can be determined for a video generation protocol that has no default duration. It reads args.duration, falls back to the protocol's defaultDuration from videoGenerationConstraints, and throws if both are undefined.

Solutions

  1. Pass an explicit integer duration in args: videoStart({ duration: 5, ... })
  2. Check the protocol's supported durations via videoGenerationConstraints before calling
  3. Verify the resolved target.protocol is the one you expect (model selector may map to a different provider)

Example fix

// before
media.videoStart({ prompt: "a cat" }, modelInput);

// after
media.videoStart({ prompt: "a cat", duration: 5 }, modelInput);
Defensive patterns

Strategy: validation

Validate before calling

const c = videoGenerationConstraints(protocol);
const duration = numberFrom(args.duration) ?? c.defaultDuration;
if (duration === undefined) throw new Error(`duration required for ${protocol}`);

Type guard

const hasDuration = (a: Record<string, unknown>): boolean =>
  typeof a.duration === "number" || a.duration === undefined;

Prevention

When it happens

Trigger: Starting a video generation with a protocol whose constraints define no defaultDuration and no duration argument supplied.

Common situations: Switching providers/protocols where one had a default and the new one doesn't; omitting duration because a previous protocol auto-filled it; args using a wrong key name so duration is never read.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at packages/core/src/media/service.ts:154

    return this.submitAndWait("image-generate", request, modelPlan, optionalString(args.idempotency_key));
  }

  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)) {

View on GitHub (pinned to 99f24806c6)