moeru-ai/airi · error · Error

The file does not contain valid JSON.

Error message

The file does not contain valid JSON.

What it means

parseLive2DMotionRecording loads an AIRI Live2D motion recording from a JSON string. The very first step is JSON.parse; if it throws, the raw text is not JSON at all, so the parser stops with this dedicated message instead of leaking the raw SyntaxError. It surfaces when a user picks a wrong or corrupted file in the motion import flow.

Source

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

  stopPlayback: () => void
  loadRecording: (nextRecording: Live2DMotionRecording) => void
  dispose: () => void
}

/**
 * Parses and validates a Live2D joystick recording at the file boundary.
 *
 * @example
 * parseLive2DMotionRecording('{"format":"airi-live2d-motion/v6", ...}')
 * // => a validated recording
 */
export function parseLive2DMotionRecording(raw: string): Live2DMotionRecording {
  let input: unknown
  try {
    input = JSON.parse(raw)
  }
  catch {
    throw new Error('The file does not contain valid JSON.')
  }

  const result = safeParse(live2dMotionRecordingSchema, input)
  if (!result.success)
    throw new Error('The file is not an AIRI Live2D motion recording.')

  const { durationMs, samples } = result.output
  if (samples[0].atMs !== 0)
    throw new Error('The first motion sample must start at 0 ms.')

  for (let index = 1; index < samples.length; index++) {
    if (samples[index].atMs < samples[index - 1].atMs)
      throw new Error('The motion samples must be in time order.')
  }

  if (samples.at(-1)!.atMs > durationMs)
    throw new Error('A motion sample occurs after the recording duration.')

View on GitHub (pinned to 9c213115f8)

Solutions

  1. Verify the file is complete, valid JSON (e.g. JSON.parse in a linter or jq) before importing
  2. Re-export the motion recording from the AIRI devtools recorder
  3. Strip BOM and any trailing commas/comments, or convert from JSONC/YAML to strict JSON
  4. Check the file was not truncated by an interrupted download/transfer
Defensive patterns

Strategy: try-catch

Validate before calling

function isValidJson(raw) {
  try {
    JSON.parse(raw)
    return true
  }
  catch {
    return false
  }
}

Try / catch

try {
  const recording = parseLive2DMotionRecording(raw)
}
catch (error) {
  if (error.message === 'The file does not contain valid JSON.')
    showImportError('Selected file is not valid JSON. Re-export the motion recording.')
  else throw error
}

Prevention

When it happens

Trigger: Calling parseLive2DMotionRecording(raw) where raw is not valid JSON: empty file, HTML error page saved as .json, truncated download, trailing commas/comments (JSONC), or a binary file selected by mistake.

Common situations: Users importing an exported motion file that was edited and broke; picking a different project's config file; BOM or encoding corruption; saving with a text editor that added non-JSON content; importing a YAML/JSON5 file.

Related errors


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