moeru-ai/airi · error · Error
The motion project contains an invalid overlay span.
Error message
The motion project contains an invalid overlay span.
What it means
parseLive2DMotionProject checks that every overlay span fits inside the project duration and has startMs <= endMs. Overlays are time-bounded modulation layers over the base motion, so a span extending beyond the timeline or inverted bounds is structurally invalid. This error is thrown when overlay.endMs > project.durationMs or overlay.startMs > overlay.endMs.
Source
Thrown at packages/stage-ui/src/features/devtools/motion/live2d/composables/keyframes.ts:467
const result = safeParse(motionProjectSchema, input)
if (!result.success)
throw new Error('The file is not an AIRI Live2D motion project.')
const project = result.output
if (project.source.durationMs !== project.durationMs)
throw new Error('The motion project source is invalid.')
if (project.source.samples[0].atMs !== 0 || project.source.samples.at(-1)!.atMs > project.durationMs)
throw new Error('The motion project source timeline is invalid.')
for (let index = 1; index < project.source.samples.length; index++) {
if (project.source.samples[index].atMs < project.source.samples[index - 1].atMs)
throw new Error('The motion project source samples are not in time order.')
}
for (const overlay of project.overlays) {
if (overlay.endMs > project.durationMs || overlay.startMs > overlay.endMs)
throw new Error('The motion project contains an invalid overlay span.')
if (overlay.points.some(point => point.atMs < overlay.startMs || point.atMs > overlay.endMs))
throw new Error('The motion project contains an invalid overlay point.')
for (let index = 1; index < overlay.points.length; index++) {
if (overlay.points[index].atMs < overlay.points[index - 1].atMs)
throw new Error('The motion project overlay points are not in time order.')
}
}
return structuredClone(project)
}
View on GitHub (pinned to 9c213115f8)
Solutions
- Clamp overlay.startMs and overlay.endMs to [0, project.durationMs] before parsing
- Ensure startMs <= endMs when constructing the overlay
- Recompute overlay spans after any change to project.durationMs
Example fix
// before overlay.startMs = userStart overlay.endMs = userEnd // after overlay.startMs = Math.max(0, Math.min(userStart, project.durationMs)) overlay.endMs = Math.max(overlay.startMs, Math.min(userEnd, project.durationMs))
Defensive patterns
Strategy: validation
Validate before calling
for (const overlay of project.overlays) {
overlay.startMs = Math.max(0, Math.min(overlay.startMs, project.durationMs))
overlay.endMs = Math.max(overlay.startMs, Math.min(overlay.endMs, project.durationMs))
} Type guard
const hasValidSpan = (o, durationMs) => o.startMs <= o.endMs && o.endMs <= durationMs
Try / catch
try {
parseLive2DMotionProject(project)
}
catch (error) {
if (error.message.includes('invalid overlay span'))
console.error('Overlay span out of bounds; clamp startMs/endMs to project durationMs')
throw error
} Prevention
- Clamp overlay bounds whenever project.durationMs changes
- Never build spans from raw user input without clamping
- Validate spans in the overlay editing UI before saving
When it happens
Trigger: Calling parseLive2DMotionProject where an overlay has startMs greater than endMs (inverted span) or endMs exceeding project.durationMs (span out of timeline bounds).
Common situations: Setting overlay bounds from user input without clamping to project.durationMs; editing project.durationMs shorter after overlays were created; copying overlay data between projects with different durations; typos swapping startMs and endMs.
Related errors
- The motion project contains an invalid overlay point.
- The crop range is outside the motion timeline.
- The motion project source samples are not in time order.
- The motion project overlay points are not in time order.
- The first motion sample must start at 0 ms.
AI-assisted analysis of moeru-ai/airi@9c213115f8 (2026-09-02).
Data as JSON: /api/errors/ed29afc438e96495.
Report an issue: GitHub.