yikart/AiToEarn · error · BadRequestException
last_frame requires first_frame
Error message
last_frame requires first_frame
What it means
Volcengine frame-interpolation generation requires a first frame when a last frame is provided. validateContent throws this BadRequestException when last_frame images exist but no first_frame image was supplied, because a last frame alone is not a valid generation mode.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/volcengine/volcengine.service.ts:171
const firstFrameImages = imageContents.filter(item => !item.role || item.role === ImageRole.FirstFrame)
const lastFrameImages = imageContents.filter(item => item.role === ImageRole.LastFrame)
const referenceImages = imageContents.filter(item => item.role === ImageRole.ReferenceImage)
const referenceVideos = videoContents.filter(item => item.role === VideoRole.ReferenceVideo)
const referenceAudios = audioContents.filter(item => item.role === AudioRole.ReferenceAudio)
const hasFrameScene = firstFrameImages.length > 0 || lastFrameImages.length > 0
const hasReferenceScene = referenceImages.length > 0 || referenceVideos.length > 0 || referenceAudios.length > 0
if (firstFrameImages.length > 1) {
throw new BadRequestException('Only one first frame image is allowed')
}
if (lastFrameImages.length > 1) {
throw new BadRequestException('Only one last frame image is allowed')
}
if (lastFrameImages.length > 0 && firstFrameImages.length === 0) {
throw new BadRequestException('last_frame requires first_frame')
}
if (hasFrameScene && hasReferenceScene) {
throw new BadRequestException('first_frame/last_frame and reference media cannot be mixed')
}
if (referenceAudios.length > 0 && referenceImages.length === 0 && referenceVideos.length === 0) {
throw new BadRequestException('reference_audio requires at least one reference image or reference video')
}
}
private normalizeRequest(request: UserVolcengineGenerationRequestDto) {
let prompt = ''
let inlineResolution: string | undefined
let inlineRatio: string | undefined
let inlineDuration: number | undefined
let inlineSeed: number | undefined
let inlineWatermark: boolean | undefinedView on GitHub (pinned to d3aa8bea5b)
Solutions
- Add a first_frame image content item alongside the last_frame
- If only one image is intended, assign it role first_frame instead
- Validate the pair client-side: last_frame implies first_frame
Example fix
// before
content: [{ type:'image_url', role:'last_frame', url: img }]
// after
content: [{ type:'image_url', role:'first_frame', url: start }, { type:'image_url', role:'last_frame', url: img }] Defensive patterns
Strategy: validation
Validate before calling
const hasLast = content.some(c => c.role === 'last_frame'); const hasFirst = content.some(c => c.role === 'first_frame'); if (hasLast && !hasFirst) throw new Error('last_frame requires first_frame') Type guard
const isValidFramePair = (c: Content[]) => !c.some(i => i.role === 'last_frame') || c.some(i => i.role === 'first_frame')
Try / catch
try { await generate(req) } catch (e) { if (e instanceof BadRequestException && e.message === 'last_frame requires first_frame') { /* add a first_frame or change role */ } else throw e } Prevention
- Pair first/last frames together in UI selection
- Never assign last_frame role to a lone image
- Pre-validate frame role dependencies client-side
When it happens
Trigger: Sending content with exactly one last_frame image and zero first_frame images.
Common situations: Client mixes up role assignment (marking the start image as last_frame); UI only collects an end frame; refactor swapped role values.
Related errors
- Only one first frame image is allowed
- Only one last frame image is allowed
- reference_audio requires at least one reference image or ref
- image_tail requires a single first frame image
- content is required
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/8aed9e090d1e023c.
Report an issue: GitHub.