{"record":{"id":"4ae40ea27ef2927b","repo":"vercel/ai","slug":"flux-3-video-requires-an-explicit-duration-when","errorCode":null,"errorMessage":"FLUX 3 video requires an explicit duration when ${UNTIMED_KEYFRAMES_NEEDING_DURATION} or more keyframes are sent without a timestamp.","messagePattern":"FLUX 3 video requires an explicit duration when (.+?) or more keyframes are sent without a timestamp\\.","errorType":"validation","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"packages/black-forest-labs/src/black-forest-labs-video-model.ts","lineNumber":521,"sourceCode":"        });\n        duration = MAX_DURATION_SECONDS;\n      } else if (duration < MIN_DURATION_SECONDS) {\n        warnings.push({\n          type: 'unsupported',\n          feature: 'duration',\n          details: `FLUX 3 video requires at least ${MIN_DURATION_SECONDS} seconds. The requested duration of ${options.duration} was clamped to ${MIN_DURATION_SECONDS}.`,\n        });\n        duration = MIN_DURATION_SECONDS;\n      }\n    }\n\n    const untimedKeyframeCount =\n      keyframes?.filter(keyframe => typeof keyframe === 'string').length ?? 0;\n    if (\n      duration == null &&\n      untimedKeyframeCount >= UNTIMED_KEYFRAMES_NEEDING_DURATION\n    ) {\n      throw new InvalidArgumentError({\n        argument: 'duration',\n        message:\n          `FLUX 3 video requires an explicit duration when ${UNTIMED_KEYFRAMES_NEEDING_DURATION} or more ` +\n          'keyframes are sent without a timestamp.',\n      });\n    }\n\n    const mode = keyframes != null ? 'i2v' : startVideo != null ? 'v2v' : 't2v';\n\n    const body: Record<string, unknown> = {\n      mode,\n      prompt: options.prompt ?? '',\n      aspect_ratio: aspectRatio,\n      duration,\n      resolution,\n      version: bflOptions?.version,\n      generate_audio: options.generateAudio,\n      safety_tolerance: bflOptions?.safetyTolerance,","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/black-forest-labs/src/black-forest-labs-video-model.ts#L503-L539","documentation":"Thrown by getArgs() of the Black Forest Labs video model when generating FLUX 3 video with multiple string keyframes (image URLs/ids without per-keyframe timestamps) but no explicit `duration` option. The BFL API cannot infer a coherent timeline for >= UNTIMED_KEYFRAMES_NEEDING_DURATION untimed keyframes, so the SDK fails fast client-side with InvalidArgumentError instead of sending a doomed request. Providing a duration, or timestamped keyframes, resolves it.","triggerScenarios":"Calling generateVideo/doGenerate on a black-forest-labs FLUX 3 video model with `keyframes` containing at least UNTIMED_KEYFRAMES_NEEDING_DURATION plain string entries and options.duration left undefined.","commonSituations":"Passing an array of image URLs as keyframes to stitch a multi-shot video without specifying duration; copying a single-keyframe example (where duration is optional) and adding more keyframes; assuming the API will auto-pick duration as it does for text-to-video.","solutions":["Add an explicit whole-number `duration` (5-20 seconds) to the video generation options.","Provide timestamps for the keyframes so they are no longer 'untimed' string entries.","Reduce the number of keyframes below the threshold if a fixed duration is not desired."],"exampleFix":"// before\nawait generateVideo({ model: bfl.video('flux-3'), prompt, keyframes: [img1, img2, img3] });\n// after\nawait generateVideo({ model: bfl.video('flux-3'), prompt, keyframes: [img1, img2, img3], duration: 10 });","handlingStrategy":"validation","validationCode":"const untimed = keyframes?.filter(k => typeof k === 'string').length ?? 0;\nif (duration == null && untimed >= 2) {\n  throw new Error('Provide an explicit duration (5-20s) or timestamped keyframes.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await generateVideo({ model, prompt, keyframes, duration });\n} catch (e) {\n  if (InvalidArgumentError.isInstance?.(e) && /duration/.test(e.message)) {\n    // re-run with a default duration\n  }\n  throw e;\n}","preventionTips":["Always pass an explicit whole-second duration (5-20) when using multiple keyframes.","Attach timestamps to keyframes when you need a precise timeline.","Wrap multi-keyframe generation in a helper that defaults duration before calling the SDK."],"tags":["video-generation","invalid-argument","fluent-input-validation","client-side"],"backgroundTag":"missing-required-option","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}