yikart/AiToEarn · error · BadRequestException
video duration is required
Error message
video duration is required
What it means
resolveVideoDuration must know the source video's duration for video2video tasks. It probes the video's metadata; if the probe fails or returns a non-positive/non-numeric duration and no explicit duration or default exists, it throws BadRequestException('video duration is required').
Source
Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/dashscope/dashscope.service.ts:139
if (!Number.isFinite(maxDuration)) {
throw new AppException(ResponseCode.InvalidModel)
}
return maxDuration
}
private async resolveVideoDuration(request: UserVideoGenerationRequestDto, modelConfig: DashscopeModelConfig, videoUrl: string | undefined): Promise<number | undefined> {
if (request.duration != null) {
return request.duration
}
if (!videoUrl) {
return modelConfig.defaults.duration
}
const metadata = await this.videoMetadataService.probeVideoMetadata(FileUtil.buildUrl(videoUrl))
const metadataDuration = Number(metadata.duration)
if (!Number.isFinite(metadataDuration) || metadataDuration <= 0) {
throw new BadRequestException('video duration is required')
}
return Math.min(Math.ceil(metadataDuration), this.getMaxDuration(modelConfig))
}
private async buildPayload(request: UserVideoGenerationRequestDto, modelConfig: DashscopeModelConfig): Promise<{
providerModel: string
mode: string
payload: DashscopeCreateVideoTaskRequest
duration?: number
resolution?: string
}> {
if (request.image_tail) {
throw new BadRequestException('DashScope HappyHorse does not support image_tail')
}
const imageUrls = this.collectImageUrls(request)
const videoUrl = request.video_url ?? request.videos?.[0]View on GitHub (pinned to d3aa8bea5b)
Solutions
- Pass an explicit duration in the request to skip metadata probing.
- Verify the video URL is accessible from the backend and the file plays correctly.
- Re-encode the video (e.g. with ffmpeg) so it carries proper duration metadata.
- Set modelConfig.defaults.duration so a default is used when probing fails.
Example fix
// before
POST /video/generate { model: '...', video_url: 'https://.../clip.mov' }
// after
POST /video/generate { model: '...', video_url: 'https://.../clip.mp4', duration: 5 } Defensive patterns
Strategy: validation
Validate before calling
if (request.video_url && request.duration == null) {
const meta = await probeVideoMetadata(request.video_url)
if (!Number.isFinite(Number(meta.duration)) || Number(meta.duration) <= 0) {
throw new Error('Source video has no readable duration; pass request.duration explicitly')
}
} Type guard
null
Try / catch
try {
await generate(request)
} catch (err) {
if (err instanceof BadRequestException && err.message === 'video duration is required') {
// re-probe the video, re-encode it, or ask the user to supply a duration
}
throw err
} Prevention
- Always send an explicit duration for video2video requests when known.
- Pre-encode uploads with ffmpeg so duration metadata is present.
- Verify the storage URL is reachable from the backend before submitting.
- Configure modelConfig.defaults.duration as a safe fallback.
When it happens
Trigger: video2video request without request.duration and without modelConfig.defaults.duration, where probing videoUrl yields no usable duration (corrupt/unreadable file, unsupported codec, unreachable URL, or a 0-second/empty video).
Common situations: Uploaded video has no duration metadata (e.g. raw stream or live recording); storage URL not accessible from the backend so the probe returns nothing; video file truncated on upload.
Related errors
- OpenAI does not support multiple images
- image_tail requires a single first frame image
- content is required
- text prompt is required
- imageSize must be one of 1K, 2K, or 4K
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/050c8713237697cb.
Report an issue: GitHub.