moeru-ai/airi · warning
[mmd] no vowel mouth morphs (あ/い/う/え/お) resolved; lip-sync c
Error message
[mmd] no vowel mouth morphs (あ/い/う/え/お) resolved; lip-sync cannot move the mouth. Available morphs:
What it means
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.
Source
Thrown at packages/stage-ui-mmd/src/components/scenes/MMD.vue:377
if (!scene)
return
componentState.value = 'loading'
disposeModel()
try {
resolved = await loadMMDModelFromSource(src, { cacheKey: props.modelId })
mesh = resolved.mesh
modelGroup = new Group()
modelGroup.add(mesh)
applyTransform()
scene.add(modelGroup)
morphs = createMorphController(mesh, morphOverrides.value)
mmdStore.availableMorphs = morphs.availableMorphs
if (!morphs.resolvedSlots.some(slot => slot.startsWith('vowel'))) {
console.warn(
'[mmd] no vowel mouth morphs (あ/い/う/え/お) resolved; lip-sync cannot move the mouth. '
+ 'Available morphs:',
morphs.availableMorphs,
)
}
emote = useMMDEmote(morphs)
gaze = createGazeController(mesh)
animation = createMMDAnimationManager(resolved.mmd, { physicsEnabled: physicsEnabled.value })
// No preset idle VMD ships yet; the runtime still advances solvers and
// physics without an animation action.
await animation.init()
animation.setIKEnabled(ikEnabled.value)
animation.setGrantEnabled(grantEnabled.value)
animation.setGravity(physicsGravity.value)
// Ensure the camera aspect matches the live canvas before fitting.View on GitHub (pinned to 677329427f)
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
Defensive patterns
Strategy: validation
Validate before calling
// After creating the morph controller
const morphs = createMorphController(mesh, morphOverrides.value)
if (!morphs.resolvedSlots.some(slot => slot.startsWith('vowel'))) {
// map actual mouth morph names from morphs.availableMorphs via morphOverrides
console.warn('[mmd] no vowel mouth morphs resolved; lip-sync disabled for this model', morphs.availableMorphs)
} Type guard
function modelSupportsLipSync(morphs: ReturnType<typeof createMorphController>): boolean {
return morphs.resolvedSlots.some(slot => slot.startsWith('vowel'))
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- [mmd] emotion ${emotion} not found
- MMD ZIP must contain a .pmx or .pmd model file
- [mmd] playAction skipped: "${name}" is not registered
- [mmd] setIdleMotion skipped: "${name}" is not registered
- [mmd] gaze: no eye bone matched (左目/右目/両目); eye tracking dis
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/6f1adf8edab9fddd.
Report an issue: GitHub.