HMCL-dev/HMCL · error · IOException

Theme pack does not contain

Error message

Theme pack does not contain 

What it means

Thrown by ThemePackManager.load when the target file is not a directory and the zip archive it opens has no regular (non-directory) entry for the manifest (theme.json). A packaged theme pack must ship the manifest, so loading aborts with an IOException.

Solutions

  1. Repackage the zip so theme.json sits at the archive root (zip the contents, not the parent folder).
  2. Verify with a zip tool that a regular file entry named theme.json exists at the root.
  3. Use ThemePackExporter.export to produce a correctly structured pack archive.
  4. Confirm the file actually is a theme pack and not another launcher archive format.

Example fix

// before (zip layout)
mytheme/background.png
// after (zip layout)
theme.json
background.png
Defensive patterns

Strategy: validation

Validate before calling

try (var reader = new ZipArchiveReader(zip)) {
    var e = reader.getEntry("theme.json");
    if (e == null || e.isDirectory()) throw new IllegalArgumentException("Zip has no root theme.json");
}

Try / catch

try { manager.load(zipPath); } catch (IOException e) { if (e.getMessage().startsWith("Theme pack does not contain")) repackageWithRootManifest(); else throw e; }

Prevention

When it happens

Trigger: Calling ThemePackManager.load on a zip file that lacks a theme.json entry, or where the manifestEntry exists but manifestEntry.isDirectory() is true (a folder entry named like the manifest).

Common situations: Renaming a resource pack or skin archive to a theme-pack extension, zipping a theme folder incorrectly so the manifest is under an extra top-level folder, or archives created by tools that stored a directory entry named theme.json.

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


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/251f91b39866b35a. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java:388

        Path normalizedFile = file.toAbsolutePath().normalize();
        try {
            if (Files.isDirectory(normalizedFile)) {
                Path manifestFile = normalizedFile.resolve(ThemePackExporter.MANIFEST_ENTRY);
                if (!Files.isRegularFile(manifestFile)) {
                    throw new IOException("Theme pack directory does not contain " + ThemePackExporter.MANIFEST_ENTRY);
                }

                ThemePackManifest manifest = JsonUtils.fromJsonFile(manifestFile, ThemePackManifest.class);
                if (manifest == null) {
                    throw new JsonParseException("Manifest is null");
                }
                return new LoadedThemePack(normalizedFile, manifest);
            }

            try (var reader = new ZipArchiveReader(normalizedFile)) {
                var manifestEntry = reader.getEntry(ThemePackExporter.MANIFEST_ENTRY);
                if (manifestEntry == null || manifestEntry.isDirectory()) {
                    throw new IOException("Theme pack does not contain " + ThemePackExporter.MANIFEST_ENTRY);
                }

                ThemePackManifest manifest;
                try (var inputStream = reader.getInputStream(manifestEntry)) {
                    manifest = JsonUtils.fromNonNullJsonFully(inputStream, ThemePackManifest.class);
                }
                return new LoadedThemePack(normalizedFile, manifest);
            }
        } catch (JsonParseException | IllegalArgumentException e) {
            throw new IOException("Invalid theme-pack manifest", e);
        }
    }

    /// Loads built-in theme pack manifests from launcher resources.
    private static @Unmodifiable List<InstalledThemePack> loadBuiltinThemePacks() {
        ArrayList<InstalledThemePack> themePacks = new ArrayList<>();
        for (String id : BUILTIN_THEME_PACK_IDS) {
            try {

View on GitHub (pinned to 24702dc5a0)