HMCL-dev/HMCL · error · IOException
Installed theme-pack asset is missing:
Error message
Installed theme-pack asset is missing:
What it means
When the theme-pack location is a directory, resolveInstalledAsset resolves the normalized entry inside it and requires the target to be a regular file. If the resolved asset path does not exist or is not a regular file (e.g. a directory), it throws this IOException naming the entry.
Solutions
- Verify the asset exists at <packDir>/<entryName> and is a regular file before resolving.
- Reinstall or re-export the theme pack so the manifest and its assets are in sync.
- Fix entry-name case to match the on-disk file, especially on case-sensitive filesystems.
Example fix
// before resolveInstalledAsset(location, manifest.getBackgroundEntry()); // after Path asset = Path.of(packDir, entry); if (Files.isRegularFile(asset)) resolveInstalledAsset(location, entry);
Defensive patterns
Strategy: validation
Validate before calling
Path asset = Path.of(packDir, ThemePackAsset.normalizeEntryName(entryName));
if (!Files.isRegularFile(asset)) {
// skip or re-export the pack; do not resolve
} Try / catch
try {
ThemePackManager.resolveInstalledAsset(location, entry);
} catch (IOException e) {
if (e.getMessage().startsWith("Installed theme-pack asset is missing")) {
// fall back to a default asset or prompt reinstall
}
} Prevention
- Reinstall packs whose unpacked directory was modified or partially deleted
- Verify manifest entry names match on-disk filenames (watch case sensitivity)
- Treat directory-installed packs as managed: do not edit files inside them
When it happens
Trigger: Calling resolveInstalledAsset() on a directory-installed pack where the referenced entry is absent from the unpacked directory, was deleted, or resolves to a subdirectory rather than a file.
Common situations: A manifest referencing assets renamed in a newer pack version; the user manually deleting files from the unpacked pack directory; case-sensitivity mismatches on Linux after a pack created on Windows.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Installed theme-pack file is missing:
- Theme pack location has no readable file:
- Theme-pack asset escapes the installed directory:
- Theme background image does not exist
- Theme-pack asset entry is empty
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/452982eb312dc594.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java:1215
public static ThemePackResource resolveInstalledAsset(ThemePackLocation location, String entryName) throws IOException {
Objects.requireNonNull(location);
String normalizedEntryName = ThemePackAsset.normalizeEntryName(entryName);
if (location instanceof ThemePackLocation.Builtin builtin) {
return resolveBuiltinAsset(builtin, normalizedEntryName);
}
@Nullable Path file = location.file();
if (file == null) {
throw new IOException("Theme pack location has no readable file: " + location);
}
Path installedFile = file.toAbsolutePath().normalize();
if (Files.isDirectory(installedFile)) {
Path assetFile = installedFile.resolve(normalizedEntryName).normalize();
if (!assetFile.startsWith(installedFile)) {
throw new IOException("Theme-pack asset escapes the installed directory: " + normalizedEntryName);
}
if (!Files.isRegularFile(assetFile)) {
throw new IOException("Installed theme-pack asset is missing: " + normalizedEntryName);
}
return new ThemePackResource.File(assetFile, normalizedEntryName);
}
if (!Files.isRegularFile(installedFile)) {
throw new IOException("Installed theme-pack file is missing: " + installedFile);
}
try (ZipArchiveReader zipFile = new ZipArchiveReader(installedFile, StandardCharsets.UTF_8)) {
ZipArchiveEntry entry = zipFile.getEntry(normalizedEntryName);
if (entry == null || entry.isDirectory()) {
throw new IOException("Installed theme-pack asset is missing: " + normalizedEntryName);
}
}
return new ThemePackResource.Zip(installedFile, normalizedEntryName);
}
/// Resolves one asset stored in a bundled theme pack.
private static ThemePackResource resolveBuiltinAsset(ThemePackLocation.Builtin builtin, String entryName) throws IOException {View on GitHub (pinned to 24702dc5a0)