moeru-ai/airi · error · Error
Textures not found
Error message
Textures not found
What it means
Inside `createFakeSettings`, after locating the single moc file, the loader filters `files` for `.png` entries as textures. If none are found it throws `Textures not found`. A Cubism model requires at least one texture page; the synthetic manifest cannot be built without one.
Source
Thrown at packages/stage-ui-live2d/src/utils/live2d-zip-loader.ts:175
}
// copy and modified from https://github.com/guansss/live2d-viewer-web/blob/f6060b2ce52c2e26b6b61fa903c837fe343f72d1/src/app/upload.ts#L81-L142
function createFakeSettings(files: string[]): ModelSettings {
const mocFiles = files.filter(file => isMocFile(file))
if (mocFiles.length !== 1) {
const fileList = mocFiles.length ? `(${mocFiles.map(f => `"${f}"`).join(',')})` : ''
throw new Error(`Expected exactly one moc file, got ${mocFiles.length} ${fileList}`)
}
const mocFile = mocFiles[0]
const modelName = basename(mocFile).replace(/\.moc3?/, '')
const textures = files.filter(f => f.endsWith('.png'))
if (!textures.length) {
throw new Error('Textures not found')
}
const motions = files.filter(f => f.endsWith('.mtn') || f.endsWith('.motion3.json'))
const physics = files.find(f => f.includes('physics'))
const pose = files.find(f => f.includes('pose'))
const settings = new Cubism4ModelSettings({
url: `${modelName}.model3.json`,
Version: 3,
FileReferences: {
Moc: mocFile,
Textures: textures,
Physics: physics,
Pose: pose,
Motions: motions.length
? {
'': motions.map(motion => ({ File: motion })),
}View on GitHub (pinned to 27111382b4)
Solutions
- Confirm the archive contains `.png` texture files alongside the moc.
- Re-export from the Live2D Cubism tool ensuring textures are bundled.
- If only `.webp`/`.jpg` exist, convert them to `.png` or supply a real `model3.json` that lists the alternate texture URIs.
- Check for case mismatches and ZIP path issues (folders, backslashes).
Example fix
// before
// archive has moc but textures are .webp only -> throws
// after
// ensure at least one .png ships in the archive
const textures = files.filter(f => f.toLowerCase().endsWith('.png'))
if (!textures.length) throw new Error('Archive must include at least one .png texture') Defensive patterns
Strategy: validation
Validate before calling
const textures = files.filter(f => f.toLowerCase().endsWith('.png'))
if (!textures.length)
throw new Error('Archive must include at least one .png texture')
createFakeSettings(files) Type guard
function hasPngTextures(files: string[]): boolean {
return files.some(f => f.toLowerCase().endsWith('.png'))
} Try / catch
try {
await loadLive2DFromArchive(blob)
} catch (e) {
if (e instanceof Error && e.message === 'Textures not found') {
// ask user to include .png textures
} else throw e
} Prevention
- Ensure the archive bundles .png textures.
- Re-export with textures included.
- Watch for case mismatches on texture extensions.
When it happens
Trigger: An archive that has a moc but no `.png` textures — textures were omitted, stored in an unsupported format (e.g. `.webp`/`.jpg` only), placed in a nested folder the flat filter still sees but with wrong casing, or stripped during packaging.
Common situations: Texture files renamed to non-png formats; an archive where textures live in a folder that was excluded; case-sensitivity on a case-sensitive filesystem (`.PNG` vs `.png` is matched, but typos like `.pn` fail); a model exported with textures referenced but not bundled.
Related errors
- Empty settings file: ${url}
- Expected exactly one moc file, got ${mocFiles.length} ${file
- Cannot find file: ${path}
- Unknown settings JSON
- Settings file not found
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/6677f695f2a20da5.
Report an issue: GitHub.