{"record":{"id":"3eb7265f711ff8ec","repo":"moeru-ai/airi","slug":"model-vue-expression-controller-initialization-f","errorCode":null,"errorMessage":"[Model.vue] Expression controller initialization failed:","messagePattern":"\\[Model\\.vue\\] Expression controller initialization failed:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/stage-ui-live2d/src/components/scenes/live2d/Model.vue","lineNumber":448,"sourceCode":"      // without idle-motion blink curves.\n      if (internalModel.eyeBlink) {\n        ;(internalModel as any).eyeBlink = null\n      }\n\n      internalModelRef.value = internalModel\n    }\n\n    emits('modelLoaded')\n  }\n  catch (error) {\n    console.error('[Live2D] Failed to load model:', error)\n    emits('error', error instanceof Error ? error : new Error(String(error)))\n  }\n  finally {\n    modelLoading.value = false\n    componentState.value = 'mounted'\n    await initExpressionController(internalModelRef.value).catch((err) => {\n      console.warn('[Model.vue] Expression controller initialization failed:', err)\n    })\n    modelLoadMutex.release()\n  }\n}\n\n/**\n * Initialise the expression controller by reading expression definitions from\n * the model settings (model3.json) and parsing each referenced exp3.json file.\n *\n * This is intentionally fire-and-forget from loadModel so that a failure in\n * expression loading does not prevent the model itself from rendering.\n */\nasync function initExpressionController(internalModel?: PixiLive2DInternalModel) {\n  // Dispose any previous state (handles model reloads)\n  expressionController.dispose()\n\n  const settings = internalModel?.settings as any\n  if (!settings)","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-ui-live2d/src/components/scenes/live2d/Model.vue#L430-L466","documentation":"In loadModel's finally, the expression controller initializes fire-and-forget: it reads expression definitions from model3.json and parses each referenced exp3.json. A failure (missing files, CORS-blocked fetch, malformed JSON) only logs this warning — by design, expression problems never block model rendering. Expressions stay unavailable until the feature is toggled or the model reloads.","triggerScenarios":"model3.json referencing exp3.json files missing from the archive; malformed exp3.json content; remote hosting without CORS blocking the expression file fetches.","commonSituations":"Community models with broken expression references; partially extracted model folders; models hosted on buckets without CORS headers.","solutions":["Verify the model archive contains every exp3.json referenced by model3.json","Re-import the complete model archive (partial extraction is a common cause)","Serve remote models with CORS headers so expression fetches succeed","Retry by toggling the expression feature or reloading the model"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"const expressions = internalModel?.settings?.expressions ?? []\nif (expressions.length === 0) return // no expression refs to parse","typeGuard":null,"tryCatchPattern":"await initExpressionController(internalModelRef.value).catch((err) => {\n  console.warn('[Model.vue] Expression controller initialization failed:', err)\n}) // fire-and-forget by design: model rendering must not depend on expressions","preventionTips":["Validate model3.json expression references when importing model archives","Serve remote models with CORS headers so exp3.json fetches succeed","Retry init by toggling the expression feature or reloading the model","Keep expression failures non-fatal: motions and rendering continue"],"tags":["live2d","expressions","exp3-json","fire-and-forget"],"backgroundTag":"live2d-expression-load-failed","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"}