moeru-ai/airi · error · Error

The file is not an AIRI Live2D motion project.

Error message

The file is not an AIRI Live2D motion project.

What it means

After JSON parsing succeeds, parseLive2DMotionProject validates the parsed object against motionProjectSchema with Valibot's safeParse. This error is thrown when the structure does not match the expected AIRI Live2D motion project schema — valid JSON, but wrong shape, missing fields, or wrong types.

Source

Thrown at packages/stage-ui/src/features/devtools/motion/live2d/composables/keyframes.ts:452

/** Serializes a motion project with its source recording and overlays. */
export function stringifyLive2DMotionProject(project: Live2DMotionProject): string {
  return `${JSON.stringify(project, null, 2)}\n`
}

/** Parses a motion project file and checks its structural and timeline invariants. */
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++) {

View on GitHub (pinned to 9c213115f8)

Solutions

  1. Compare the file against the current motionProjectSchema fields (source.durationMs, source.samples with atMs/values, durationMs, overlays) and fix missing/mistyped fields.
  2. Re-export the project with the current version of the AIRI motion devtools to regenerate a schema-compliant file.
  3. Check for schema version drift between the exporting tool and this code; migrate the file to the current schema.
  4. Log result.issues from safeParse(motionProjectSchema, input) locally during debugging to see exactly which fields fail.

Example fix

// before
parseLive2DMotionProject('{ "frames": [...] }') // wrong shape
// after
parseLive2DMotionProject(JSON.stringify({
  durationMs: 1000,
  source: { durationMs: 1000, samples: [{ atMs: 0, values: {} }] },
  overlays: []
}))
Defensive patterns

Strategy: validation

Validate before calling

import { safeParse } from 'valibot'
import { motionProjectSchema } from './keyframes' // wherever exported

function isMotionProjectLike(raw) {
  try {
    return safeParse(motionProjectSchema, JSON.parse(raw)).success
  }
  catch {
    return false
  }
}

Type guard

function isMotionProject(value) {
  return safeParse(motionProjectSchema, value).success
}

Try / catch

try {
  const project = parseLive2DMotionProject(raw)
}
catch (error) {
  if (error.message === 'The file is not an AIRI Live2D motion project.') {
    notifyUser('This JSON is not an AIRI Live2D motion project. Check the exporter version.')
  }
  else throw error
}

Prevention

When it happens

Trigger: Calling parseLive2DMotionProject with JSON that parses but lacks required motionProjectSchema fields (e.g. missing source.samples, durationMs as a string, overlays not an array) or contains unknown/incompatible shapes from an older or different tool.

Common situations: Importing a motion file exported by another application or an older AIRI schema version; hand-edited JSON with renamed or deleted fields; JSON that is a valid object of a different kind (e.g. a generic keyframe config).

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


AI-assisted analysis of moeru-ai/airi@9c213115f8 (2026-09-02). Data as JSON: /api/errors/4ab69dc2c853713a. Report an issue: GitHub.