moeru-ai/airi · warning

[mmd] motion "${descriptor.name}" loaded but has 0 tracks ma

Error message

[mmd] motion "${descriptor.name}" loaded but has 0 tracks matching this model. The VMD's bone/morph names likely do not match the model (different rig/naming).

What it means

loadMMDAnimationClip() parsed the VMD file into an AnimationClip, but the clip has zero tracks for the current model: no bone or morph name in the VMD matched the loaded PMX/PMD rig. The clip is still registered under the descriptor name but will animate nothing.

Source

Thrown at packages/stage-ui-mmd/src/components/scenes/MMD.vue:338

  for (const descriptor of availableMotions.value) {
    if (registeredMotions.has(descriptor.name))
      continue
    try {
      // The VMD file lives in IndexedDB (shared across windows); build a
      // window-local object URL to load it, then revoke it once parsed.
      const file = await mmdStore.getMotionFile(descriptor.id)
      if (!file) {
        console.warn(`[mmd] motion file "${descriptor.name}" (${descriptor.id}) not found in storage`)
        continue
      }
      const url = URL.createObjectURL(file)
      try {
        const clip = await loadMMDAnimationClip(url, mesh)
        animation.registerClip(descriptor.name, clip)
        registeredMotions.add(descriptor.name)
        if (clip.tracks.length === 0) {
          console.warn(
            `[mmd] motion "${descriptor.name}" loaded but has 0 tracks matching this model. `
            + 'The VMD\'s bone/morph names likely do not match the model (different rig/naming).',
          )
        }
      }
      finally {
        URL.revokeObjectURL(url)
      }
    }
    catch (err) {
      console.error('[mmd] failed to load motion', descriptor.name, errorMessageFrom(err))
      emit('error', err)
    }
  }

  if (idleMotionName.value && registeredMotions.has(idleMotionName.value))
    animation.setIdleMotion(idleMotionName.value)
}

View on GitHub (pinned to 677329427f)

Solutions

  1. Use a VMD authored for the same model or rig family — confirm the model has the bones the motion drives (e.g. センター/center, 腰/hips)
  2. Retarget the VMD onto the target model's bone names with a tool (Blender MMD tools, CATS)
  3. Confirm the intended PMX/PMD model was loaded — a wrong model with the same motion produces the same warning
  4. For morph-only or camera VMDs where bone motion is not required, this warning can be ignored
Defensive patterns

Strategy: validation

Validate before calling

// After building the clip, before registering it
const clip = await loadMMDAnimationClip(url, mesh)
if (clip.tracks.length === 0) {
  console.warn(`[mmd] motion "${descriptor.name}" has 0 tracks matching this model; skipping registration`)
  continue
}
animation.registerClip(descriptor.name, clip)

Type guard

function clipMatchesModel(clip: AnimationClip): boolean {
  return clip.tracks.length > 0
}

Prevention

When it happens

Trigger: Using a VMD authored for a different model family: Japanese vs English/localized bone names, bones absent from the target model, or morph-only VMDs whose morph names do not exist on the model.

Common situations: Downloading a motion made for one character and applying it to another model; mixing rigs (e.g. a Tda-style rig vs a standard rig); VMDs targeting IK/appendage bones the target model does not have.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/296fd6b42b1da2de. Report an issue: GitHub.