{"record":{"id":"7dfa5f2ec7a24604","repo":"musistudio/claude-code-router","slug":"aspect-ratio-must-be-one-of-constraints-aspectra","errorCode":null,"errorMessage":"aspect_ratio must be one of ${constraints.aspectRatios.join(\", \")} for ${target.protocol}.","messagePattern":"aspect_ratio must be one of (.+?) for (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/media/service.ts","lineNumber":173,"sourceCode":"    if (!Number.isInteger(durationValue)) throw new Error(\"duration must be an integer number of seconds.\");\n    if (constraints.durations && !constraints.durations.includes(durationValue)) {\n      throw new Error(`duration must be one of ${constraints.durations.join(\", \")} seconds for ${target.protocol}.`);\n    }\n    if (constraints.durationMinimum !== undefined && constraints.durationMaximum !== undefined &&\n      (durationValue < constraints.durationMinimum || durationValue > constraints.durationMaximum)) {\n      throw new Error(`duration must be between ${constraints.durationMinimum} and ${constraints.durationMaximum} seconds for ${target.protocol}.`);\n    }\n    const resolution = optionalString(args.resolution) ?? constraints.defaultResolution;\n    if (!resolution) throw new Error(`resolution is required for ${target.protocol}.`);\n    if (!constraints.resolutions.includes(resolution)) {\n      throw new Error(`resolution must be one of ${constraints.resolutions.join(\", \")} for ${target.protocol}.`);\n    }\n    const aspectRatio = optionalString(args.aspect_ratio);\n    if (constraints.requiredParameters.includes(\"aspect_ratio\") && !aspectRatio) {\n      throw new Error(`aspect_ratio is required for ${target.protocol}.`);\n    }\n    if (aspectRatio && !constraints.aspectRatios.includes(aspectRatio)) {\n      throw new Error(`aspect_ratio must be one of ${constraints.aspectRatios.join(\", \")} for ${target.protocol}.`);\n    }\n    const request: VideoGenerateRequest = {\n      aspectRatio,\n      duration: durationValue,\n      images: args.images === undefined && args.image === undefined ? [] : this.validateImages(args.images ?? args.image, 1, 7),\n      prompt: requiredPrompt(args.prompt),\n      resolution\n    };\n    const job = this.submit(\"video-generate\", request, modelPlan, optionalString(args.idempotency_key));\n    return this.publicJob(job);\n  }\n\n  getJob(id: string): PublicMediaJob {\n    const job = this.jobStore.get(id);\n    if (!job) throw new Error(`Media job not found: ${id}`);\n    return this.publicJob(job);\n  }\n","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/media/service.ts#L155-L191","documentation":"Thrown when an aspect_ratio was supplied but is not in the protocol's aspectRatios allowlist. The message lists the accepted values.","triggerScenarios":"Passing aspect_ratio: \"4:3\" to a protocol that only supports [\"16:9\",\"9:16\"], or using alternate notations like \"landscape\" or \"1.777\".","commonSituations":"Provider-specific ratio vocabularies (16:9 vs widescreen vs 1792x1024); user free-text input; hardcoded values from a different provider integration.","solutions":["Use an exact value from the error message's allowlist","Build the UI selector from videoGenerationConstraints(protocol).aspectRatios","If aspect ratio is optional, omit it rather than guessing an invalid value"],"exampleFix":"// before\nmedia.videoStart({ ..., aspect_ratio: \"landscape\" }, modelInput);\n\n// after\nmedia.videoStart({ ..., aspect_ratio: \"16:9\" }, modelInput);","handlingStrategy":"validation","validationCode":"const c = videoGenerationConstraints(protocol);\nif (args.aspect_ratio && !c.aspectRatios.includes(args.aspect_ratio)) {\n  args.aspect_ratio = c.aspectRatios[0]; // snap to first allowed\n}","typeGuard":"const isAllowedAspectRatio = (a: string, c: VideoConstraints): boolean =>\n  c.aspectRatios.includes(a);","tryCatchPattern":null,"preventionTips":["Use the provider's exact ratio strings","Omit aspect_ratio instead of guessing"],"tags":["media","video","validation","aspect-ratio","allowed-values"],"backgroundTag":"parameter-validation-failed","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}