HMCL-dev/HMCL · error · IOException
Unsupported theme-pack entry
Error message
Unsupported theme-pack entry: ${entryName} What it means
Theme packs allow only the manifest entry and asset entries under 'assets/'. Any other entry name causes checkSupportedThemePackEntry to throw this IOException, enforcing the pack's file layout and preventing unexpected files from being extracted.
Solutions
- Repack the zip with only theme-pack.json and an assets/ directory at the root.
- Move all media files under assets/ inside the archive.
- Exclude OS metadata (e.g. `zip -x '__MACOSX*' '*.DS_Store'`) when creating the archive.
- Use ThemePackExporter so only supported entries are written.
Example fix
// before zip -r pack.zip theme-pack.json assets images/ README.md // after zip -r pack.zip theme-pack.json assets -x '*.DS_Store' '__MACOSX*'
Defensive patterns
Strategy: validation
Validate before calling
for (var e : Collections.list(new ZipFile(pack).entries())) {
String n = e.getName();
if (!n.equals("theme-pack.json") && !n.equals("assets") && !n.startsWith("assets/")) throw new IllegalArgumentException("unsupported entry: " + n);
} Try / catch
try {
ThemePackManager.install(pack, dir);
} catch (IOException e) {
if (e.getMessage().contains("Unsupported theme-pack entry")) {
ui.show("Pack contains unsupported files; remove them or re-export via the exporter.");
} else throw e;
} Prevention
- Keep packs to exactly theme-pack.json + assets/.
- Exclude __MACOSX, .DS_Store, Thumbs.db when zipping.
- Put all media under assets/.
When it happens
Trigger: Installing a zip containing stray files at the root (README.md, .DS_Store, __MACOSX/,Thumbs.db, license.txt) or assets stored outside the assets/ directory (e.g. 'images/bg.png').
Common situations: macOS Finder zips adding __MACOSX/ and .DS_Store entries; hand-built packs with a top-level 'images' or 'skins' folder; old/experimental layouts from other versions.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Duplicate theme-pack entry
- Duplicate theme-pack zip entry:
- Installed theme-pack file is missing:
- Theme-pack asset is missing
- Theme pack does not contain
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/b573f564a9029fec.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java:1428
if (segment.isEmpty() || ".".equals(segment) || "..".equals(segment)) {
throw new IOException("Theme-pack entry contains an unsafe segment: " + entryName);
}
for (int i = 0; i < segment.length(); i++) {
char ch = segment.charAt(i);
if (Character.isISOControl(ch) || ch == '\0') {
throw new IOException("Theme-pack entry contains a control character: " + entryName);
}
}
}
return normalized;
}
/// Checks that a theme-pack zip entry belongs to the current file layout.
private static void checkSupportedThemePackEntry(String entryName) throws IOException {
if (!ThemePackExporter.MANIFEST_ENTRY.equals(entryName)
&& !"assets".equals(entryName)
&& !entryName.startsWith("assets/")) {
throw new IOException("Unsupported theme-pack entry: " + entryName);
}
}
/// Deletes an existing file, symbolic link, or directory tree.
private static void deleteIfExists(Path path) throws IOException {
if (Files.exists(path) || Files.isSymbolicLink(path)) {
FileUtils.forceDelete(path);
}
}
/// Creates the background model for the current launcher settings.
private static ThemeBackgroundSettings createCurrentBackground(
List<ThemePackAsset> assets,
List<Path> temporaryFiles) throws IOException {
ResolvedBackground background = resolveCurrentBackground(currentResolveContext());
Double opacity = background.opacity();
return switch (background.type()) {
case DEFAULT -> new ThemeBackgroundSettings(View on GitHub (pinned to 24702dc5a0)