moeru-ai/airi · error · Error
Cannot find file: ${path}
Error message
Cannot find file: ${path} What it means
`ZipLoader.readText(jsZip, path)` looks up a file by `path` inside the JSZip instance via `jsZip.file(path)`. If no entry matches (returns a falsy value), it throws `Cannot find file: <path>`. This patched reader is invoked by the Live2D runtime when it tries to load a referenced asset (moc, texture, motion, physics) from the archive.
Source
Thrown at packages/stage-ui-live2d/src/utils/live2d-zip-loader.ts:210
'': motions.map(motion => ({ File: motion })),
}
: undefined,
},
})
settings.name = modelName
// provide this property for FileLoader
Object.assign(settings, { _objectURL: `example://${settings.url}` })
return settings
}
ZipLoader.readText = async (jsZip: JSZip, path: string) => {
const file = jsZip.file(path)
if (!file) {
throw new Error(`Cannot find file: ${path}`)
}
const text = await file.async('text')
return isSettingsFile(path) ? sanitizeModelSettingsText(text) : text
}
const defaultFileLoaderReadText = FileLoader.readText
FileLoader.createSettings = async (files: File[]) => {
const settingsFile = files.find(file => isSettingsFile(file.webkitRelativePath || file.name))
if (!settingsFile) {
throw new TypeError('Settings file not found')
}
const settingsUrl = settingsFile.webkitRelativePath || settingsFile.name
const settingsText = await FileLoader.readText(settingsFile)
const settings = createModelSettings(settingsText, settingsUrl)View on GitHub (pinned to 27111382b4)
Solutions
- Cross-check every path in `FileReferences` against the actual ZIP entries (case- and separator-sensitive).
- Normalize separators to `/` and remove leading `./` in manifest references.
- Ensure all referenced assets (moc, textures, motions, physics, pose, display names) are included in the archive.
- If a reference is optional, mark it correctly so the runtime does not request it.
Example fix
// before // manifest Moc: "Model/Moc/model.moc3" but archive has "model.moc3" at root // after // align manifest paths with archive layout, or move the file to match Moc: "model.moc3" Textures: ["texture_00.png"]
Defensive patterns
Strategy: validation
Validate before calling
const exists = !!zip.file(path)
if (!exists) throw new Error(`Cannot find file: ${path}`)
await ZipLoader.readText(zip, path) Type guard
function zipHasPath(zip: JSZip, path: string): boolean {
return !!zip.file(path)
} Try / catch
try {
await loadLive2DFromArchive(blob)
} catch (e) {
if (e instanceof Error && e.message.startsWith('Cannot find file:')) {
// inspect manifest references vs archive entries
} else throw e
} Prevention
- Align manifest paths with archive layout (case- and separator-sensitive).
- Normalize backslashes to '/' and strip leading './'.
- Bundle every referenced asset (moc, textures, motions, physics, pose).
When it happens
Trigger: The model manifest references a file (e.g. `FileReferences.Moc` or a texture path) that does not exist in the ZIP, or the path casing/separator differs from the actual archive entry (`\` vs `/`, leading `./`, nested folder mismatch).
Common situations: Manifest edited by hand with a wrong path; model packaged on Windows with backslashes; case-sensitivity mismatch between a macOS-authored manifest and a Linux extractor; a referenced motion/physics file omitted from the archive.
Related errors
- Empty settings file: ${url}
- Expected exactly one moc file, got ${mocFiles.length} ${file
- Textures not found
- Unknown settings JSON
- Settings file not found
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/a1cfe03c5ac611ac.
Report an issue: GitHub.