yikart/AiToEarn · error · BadRequestException
DashScope HappyHorse does not support image_tail
Error message
DashScope HappyHorse does not support image_tail
What it means
buildPayload for DashScope HappyHorse models rejects requests containing image_tail, since the DashScope HappyHorse API has no tail-image capability. It throws BadRequestException immediately before building the payload.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/dashscope/dashscope.service.ts:153
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]
const mode = this.resolveMode(request, modelConfig, imageUrls)
const resolution = request.resolution
const providerModel = this.getProviderModel(modelConfig, mode, resolution)
const ratio = request.ratio
const duration = await this.resolveVideoDuration(request, modelConfig, mode === 'video2video' ? videoUrl : undefined)
const prompt = request.prompt
const parameters: NonNullable<DashscopeCreateVideoTaskRequest['parameters']> = {}
if (resolution) {
parameters.resolution = resolution
}
parameters.watermark = request.watermark ?? false
if (request.seed != null) {
parameters.seed = request.seed
}View on GitHub (pinned to d3aa8bea5b)
Solutions
- Omit image_tail for DashScope HappyHorse requests; use only image_head.
- Route requests needing image_tail to a provider/model that supports it.
- Strip image_tail in an adapter layer before calling DashScope generation.
- If image_tail was intended as a second reference image, move it into the images array (respecting image count limits).
Example fix
// before
{ model: 'wan-happyhorse', image_head: urlA, image_tail: urlB }
// after
{ model: 'wan-happyhorse', image_head: urlA } // image_tail unsupported on DashScope Defensive patterns
Strategy: validation
Validate before calling
if (model.startsWith('wan-happyhorse') && request.image_tail) {
throw new Error('Strip image_tail before calling DashScope HappyHorse; it is unsupported')
} Type guard
function happyhorseSafe<T extends { image_tail?: string }>(req: T, model: string): Omit<T, 'image_tail'> {
return model.includes('happyhorse') ? omit(req, 'image_tail') : req
} Try / catch
try {
await generate(request)
} catch (err) {
if (err.message.includes('does not support image_tail')) {
const { image_tail, ...rest } = request
return generate(rest as typeof request) // retry without the unsupported field
}
throw err
} Prevention
- Gate image_tail UI on provider capability, not on generic 'video generation'.
- Maintain a per-model capability matrix in the client.
- Sanitize request DTOs per provider in an adapter layer.
When it happens
Trigger: Any video generation request to a HappyHorse (DashScope) model with request.image_tail set (e.g. clients that support start/end frames for other providers reusing the same DTO).
Common situations: Frontend sends image_tail unconditionally when a user supplies a second frame image; code shared across providers (e.g. one that supports image_tail like Kling) targeting DashScope.
Related errors
- No response from Gemini
- InvalidModel
- video duration is required
- DashScope task id is missing
- InvalidAiTaskId
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/bf25b2ad05dfaa55.
Report an issue: GitHub.