HMCL-dev/HMCL · error · IllegalArgumentException

Duplicate theme-pack zip entry:

Error message

Duplicate theme-pack zip entry: 

What it means

Thrown by ThemePackExporter.validateAssets when two or more assets map to the same zip entry name. A zip archive cannot contain duplicate entries reliably, so the exporter detects collisions in its entry-name set before writing the target file.

Solutions

  1. Deduplicate the asset list by entryName() before calling export.
  2. Use a Map keyed by entry name when building assets so later entries replace earlier ones.
  3. Give colliding assets distinct entry names if both are truly needed.
  4. Log or merge duplicate registrations at asset-collection time instead of passing them through.

Example fix

// before
assets.add(ThemePackAsset.of("background.png", a));
assets.add(ThemePackAsset.of("background.png", b));
// after
assets.add(ThemePackAsset.of("background.png", b)); // keep only one entry per name
Defensive patterns

Strategy: validation

Validate before calling

java.util.Set<String> seen = new java.util.HashSet<>();
for (ThemePackAsset a : assets) {
    if (!seen.add(a.entryName())) throw new IllegalStateException("Duplicate entry: " + a.entryName());
}

Try / catch

try { ThemePackExporter.export(pack, assets, out); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Duplicate theme-pack zip entry")) dedupeAssets(); throw e; }

Prevention

When it happens

Trigger: Calling ThemePackExporter.export with an asset list where two ThemePackAsset items return the same entryName() — e.g. adding background.png twice, or two files in different source dirs assigned the same entry name.

Common situations: Programmatic asset assembly that appends defaults and user overrides without deduplication, copy-pasted asset registrations, or generating entry names that ignore case/extension differences that still normalize identically.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackExporter.java:111

        }
    }

    /// Validates all asset entries and source files before the zip is written.
    private static void validateAssets(List<ThemePackAsset> assets) throws IOException {
        Set<String> entries = new HashSet<>();
        entries.add(MANIFEST_ENTRY);

        for (ThemePackAsset asset : assets) {
            Objects.requireNonNull(asset);
            @Nullable Path sourceFile = asset.source().file();
            if (sourceFile != null && !Files.isRegularFile(sourceFile)) {
                throw new IOException("Theme-pack asset source is not a regular file: " + sourceFile);
            }
            try (InputStream ignored = asset.source().openStream()) {
                // Validate readability before writing the target zip.
            }
            if (!entries.add(asset.entryName())) {
                throw new IllegalArgumentException("Duplicate theme-pack zip entry: " + asset.entryName());
            }
        }
    }
}

View on GitHub (pinned to 24702dc5a0)