{"record":{"id":"59b20c43dc2f849a","repo":"moeru-ai/airi","slug":"no-vrm-animations-found-in-the-vrma-file","errorCode":null,"errorMessage":"No VRM animations found in the .vrma file","messagePattern":"No VRM animations found in the \\.vrma file","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/stage-ui-three/src/composables/vrm/animation.ts","lineNumber":26,"sourceCode":"import { randFloat } from 'three/src/math/MathUtils.js'\nimport { ref } from 'vue'\n\nimport { useVRMLoader } from './loader'\nimport { randomSaccadeInterval } from './utils/eye-motions'\n\nexport interface GLTFUserdata extends Record<string, any> {\n  vrmAnimations: VRMAnimation[]\n}\n\nexport async function loadVRMAnimation(url: string) {\n  const loader = useVRMLoader()\n\n  // load VRM Animation .vrma file\n  const gltf = await loader.loadAsync(url)\n\n  const userData = gltf.userData as GLTFUserdata\n  if (!userData.vrmAnimations) {\n    console.warn('No VRM animations found in the .vrma file')\n    return\n  }\n  if (userData.vrmAnimations.length === 0) {\n    console.warn('No VRM animations found in the .vrma file')\n    return\n  }\n\n  return userData.vrmAnimations[0]\n}\n\nexport async function clipFromVRMAnimation(vrm?: VRMCore, animation?: VRMAnimation) {\n  if (!vrm) {\n    console.warn('No VRM found')\n    return\n  }\n  if (!animation) {\n    return\n  }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-ui-three/src/composables/vrm/animation.ts#L8-L44","documentation":"loadVRMAnimation() loads a .vrma file through the GLTF loader with pixiv's VRM animation plugin; the plugin writes parsed clips into gltf.userData.vrmAnimations only when the glTF carries the VRMC_vrm_animation extension. This warn fires when the property is entirely absent: the file was fetched and parsed as glTF JSON, but the loader never recognized it as a VRM animation. The function returns undefined, so downstream code must tolerate that.","triggerScenarios":"Passing a URL that resolves to a .vrm model or generic glTF instead of a .vrma; the server returning a 200 JSON error page; the GLTFLoader being created without the VRM animation plugin registered (useVRMLoader misconfigured); a three-vrm version that predates VRMA support.","commonSituations":"Wrong/moved asset URL behind a CDN or static host that serves a JSON body with 200; upgrading @pixiv/three-vrm and the plugin registration code drifting; hand-authored .vrma files missing the extensions block.","solutions":["Open the URL directly and confirm the body is a real .vrma glTF with \"extensions\" containing VRMC_vrm_animation.","Verify useVRMLoader registers the VRM animation plugin on the GLTFLoader used by loadAsync.","Upgrade @pixiv/three-vrm / @pixiv/three-vrm-core to a release that supports the VRMA spec version of your file.","Handle the undefined return so UI does not silently keep a broken animation state."],"exampleFix":"// before\nconst anim = await loadVRMAnimation(url) // may be undefined, warns\n\n// after\nconst anim = await loadVRMAnimation(url)\nif (!anim) {\n  // fetch and inspect the file; surface a user-visible error\n  throw new Error(`File at ${url} is not a valid .vrma (no VRMC_vrm_animation extension)`)\n}","handlingStrategy":"validation","validationCode":"const res = await fetch(url)\nconst json = await res.json().catch(() => null)\nconst isVrma = !!json?.extensionsUsed?.includes?.('VRMC_vrm_animation')\n  || !!json?.extensions?.VRMC_vrm_animation\nif (!isVrma) throw new Error('Not a .vrma file')","typeGuard":"function hasVrmAnimations(gltf: unknown): gltf is { userData: { vrmAnimations: unknown[] } } {\n  return Array.isArray((gltf as { userData?: { vrmAnimations?: unknown[] } })?.userData?.vrmAnimations)\n}","tryCatchPattern":"try {\n  const anim = await loadVRMAnimation(url)\n  if (!anim) return // warned inside; degrade to no idle animation\n  const clip = await clipFromVRMAnimation(vrm, anim)\n} catch (err) {\n  console.error('vrma load failed', errorMessageFrom(err))\n}","preventionTips":["Serve .vrma with correct content-type and verify URLs return the file, not a fallback page.","Assert loader plugin registration in useVRMLoader before first load.","Pin three-vrm versions and add a smoke test that loads one known-good .vrma in CI."],"tags":["vrm","vrma","gltf","loader","three-vrm"],"backgroundTag":"missing-gltf-extension","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}