{"record":{"id":"6f1adf8edab9fddd","repo":"moeru-ai/airi","slug":"mmd-no-vowel-mouth-morphs-resolved","errorCode":null,"errorMessage":"[mmd] no vowel mouth morphs (あ/い/う/え/お) resolved; lip-sync cannot move the mouth. Available morphs:","messagePattern":"\\[mmd\\] no vowel mouth morphs \\(あ/い/う/え/お\\) resolved; lip-sync cannot move the mouth\\. Available morphs:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/stage-ui-mmd/src/components/scenes/MMD.vue","lineNumber":377,"sourceCode":"  if (!scene)\n    return\n\n  componentState.value = 'loading'\n  disposeModel()\n\n  try {\n    resolved = await loadMMDModelFromSource(src, { cacheKey: props.modelId })\n    mesh = resolved.mesh\n\n    modelGroup = new Group()\n    modelGroup.add(mesh)\n    applyTransform()\n    scene.add(modelGroup)\n\n    morphs = createMorphController(mesh, morphOverrides.value)\n    mmdStore.availableMorphs = morphs.availableMorphs\n    if (!morphs.resolvedSlots.some(slot => slot.startsWith('vowel'))) {\n      console.warn(\n        '[mmd] no vowel mouth morphs (あ/い/う/え/お) resolved; lip-sync cannot move the mouth. '\n        + 'Available morphs:',\n        morphs.availableMorphs,\n      )\n    }\n\n    emote = useMMDEmote(morphs)\n    gaze = createGazeController(mesh)\n\n    animation = createMMDAnimationManager(resolved.mmd, { physicsEnabled: physicsEnabled.value })\n    // No preset idle VMD ships yet; the runtime still advances solvers and\n    // physics without an animation action.\n    await animation.init()\n    animation.setIKEnabled(ikEnabled.value)\n    animation.setGrantEnabled(grantEnabled.value)\n    animation.setGravity(physicsGravity.value)\n\n    // Ensure the camera aspect matches the live canvas before fitting.","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-ui-mmd/src/components/scenes/MMD.vue#L359-L395","documentation":"After loading the MMD model, createMorphController(mesh, morphOverrides) resolves morph slots; none of them started with 'vowel', so the あ/い/う/え/お lip-sync morphs were not found on the model. Audio-driven lip sync will not move the mouth; rendering, motion, gaze and emotes still work.","triggerScenarios":"The PMX model lacks standard Japanese vowel morphs — renamed, English-only names (A/I/U/E/O) not matched by the resolver, or missing entirely — or the morphOverrides config remaps vowel slots to morph names that do not exist on the model.","commonSituations":"Western-made MMD models with English morph names; models using variant names like あ2 that the resolver does not map; a user-supplied morph override config pointing at wrong names.","solutions":["Inspect morphs.availableMorphs (logged with the warning) and map the actual mouth morphs to vowel slots via morphOverrides","Fix or add the standard vowel morphs あ/い/う/え/お to the model in a PMX editor","If you configured morph overrides, verify every override name exists exactly in the model's morph list","Accept reduced functionality if lip sync is not required for this model"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// After creating the morph controller\nconst morphs = createMorphController(mesh, morphOverrides.value)\nif (!morphs.resolvedSlots.some(slot => slot.startsWith('vowel'))) {\n  // map actual mouth morph names from morphs.availableMorphs via morphOverrides\n  console.warn('[mmd] no vowel mouth morphs resolved; lip-sync disabled for this model', morphs.availableMorphs)\n}","typeGuard":"function modelSupportsLipSync(morphs: ReturnType<typeof createMorphController>): boolean {\n  return morphs.resolvedSlots.some(slot => slot.startsWith('vowel'))\n}","tryCatchPattern":null,"preventionTips":["Check the model's morph list for あ/い/う/え/お (or their localized equivalents) before enabling lip sync","Use morphOverrides to map English morph names (A/I/U/E/O) onto vowel slots","Disable lip-sync UI affordances when vowel slots cannot resolve"],"tags":["mmd","morphs","lip-sync","vowel-morphs"],"backgroundTag":"missing-morph-targets","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}