moeru-ai/airi · error · Error
The motion project source timeline is invalid.
Error message
The motion project source timeline is invalid.
What it means
After schema validation, parseLive2DMotionProject checks timeline invariants that the schema alone cannot express: the first source sample must start at atMs 0 and the last sample must not exceed project.durationMs. A violation means the source timeline does not cover/align with the project timeline and cannot be reliably resampled.
Source
Thrown at packages/stage-ui/src/features/devtools/motion/live2d/composables/keyframes.ts:459
export function parseLive2DMotionProject(raw: string): Live2DMotionProject {
let input: unknown
try {
input = JSON.parse(raw)
}
catch {
throw new Error('The file does not contain valid JSON.')
}
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
- Ensure the first sample has atMs: 0; rebase all sample timestamps by subtracting samples[0].atMs.
- Remove or clamp samples whose atMs exceeds project.durationMs, or increase durationMs to cover the last sample.
- Re-export the project from the AIRI motion devtools to regenerate a correctly aligned sample timeline.
Example fix
// before
samples: [{ atMs: 120, values: {...} }, { atMs: 2400, values: {...} }] // durationMs: 2000
// after
samples: [{ atMs: 0, values: {...} }, { atMs: 2000, values: {...} }] Defensive patterns
Strategy: validation
Validate before calling
function hasAlignedTimeline(parsed) {
const samples = parsed?.source?.samples
if (!Array.isArray(samples) || samples.length === 0)
return false
return samples[0].atMs === 0
&& samples[samples.length - 1].atMs <= parsed.durationMs
} Try / catch
try {
const project = parseLive2DMotionProject(raw)
}
catch (error) {
if (error.message === 'The motion project source timeline is invalid.') {
notifyUser('Motion samples do not align with the project timeline (must start at 0ms and end within durationMs).')
}
else throw error
} Prevention
- Always anchor the first sample at atMs: 0 when generating or trimming samples.
- Clamp or drop samples beyond durationMs before export.
- Rebase timestamps when externally cropping samples (subtract the crop start).
- Include timeline alignment checks in your exporter's test suite.
When it happens
Trigger: Parsing a project whose source.samples[0].atMs is not 0 (e.g. samples start at 100ms) or whose last sample's atMs exceeds project.durationMs (e.g. last sample at 2500ms with durationMs 2000).
Common situations: Hand-trimming sample arrays without rebasing timestamps to 0; cropping samples externally and leaving the original end timestamp; exporter bug writing samples beyond the declared duration.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- The motion project source is invalid.
- The first motion sample must start at 0 ms.
- A motion sample occurs after the recording duration.
- The MAGIC frame must contain ${poseAxes.length} Live2D value
- Archive entry not found: ${filePath}
AI-assisted analysis of moeru-ai/airi@9c213115f8 (2026-09-02).
Data as JSON: /api/errors/a3fc8b91faa81328.
Report an issue: GitHub.