HMCL-dev/HMCL · error · NoSuchFileException
Subdirectory does not exist in the zip file.
Error message
Subdirectory <subDirectory> does not exist in the zip file.
What it means
Thrown by Unzipper when the configured subDirectory does not exist in the zip file being extracted. Detection is indirect: if no entries at all matched the subDirectory prefix (entryCount == 0), the subdirectory is assumed absent. Suppressed when terminateIfSubDirectoryNotExists is set to true or subDirectory is '/'.
Solutions
- Verify the subDirectory string matches the actual entry prefix in the zip (list entries first, e.g. with ZipFile.getEntries).
- Check for trailing-slash and case mismatches against entry names.
- Set terminateIfSubDirectoryNotExists(true) if an empty result is acceptable.
- Fall back to extracting the whole archive when the subdirectory is missing.
Example fix
// before
new Unzipper(zipFile, destDir).subDirectory("Assets/").unzip();
// after
new Unzipper(zipFile, destDir).subDirectory("assets/").unzip(); Defensive patterns
Strategy: validation
Validate before calling
boolean exists;
try (ZipFile zf = new ZipFile(zipFile.toFile())) {
exists = zf.getEntries().asIterator().hasNext()
&& zf.getEntries().asIterator().next() != null; // then check prefix in real code
}
// concretely: stream entry names and test name.startsWith(subDirectory) Try / catch
try {
new Unzipper(zip, dest).subDirectory(sub).unzip();
} catch (NoSuchFileException e) {
// subdirectory absent; extract whole archive or skip
} Prevention
- List zip entries and verify the subDirectory prefix before extracting.
- Normalize trailing slashes and casing when building subDirectory.
- Set terminateIfSubDirectoryNotExists(true) when absence is acceptable.
When it happens
Trigger: Calling unzip() with subDirectory set to a path that has no matching entries in the zip (typo, wrong casing, or directory genuinely absent) while terminateIfSubDirectoryNotExists is false.
Common situations: Extracting a specific folder (e.g. 'assets/') from a mod jar or resource zip whose internal layout changed between versions; zip built with different top-level folder name; case-sensitivity mismatch.
Related errors
- Theme pack does not contain
- Theme pack directory does not contain
- Not a valid world zip file since level.dat or…
- Cannot find suitable encoding for the zip.
- Not a zip file
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/c9babb455e5bbec2.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/Unzipper.java:156
} catch (FileAlreadyExistsException ignored) {
}
} else {
try (InputStream input = reader.getInputStream(entry)) {
Files.copy(input, destFile, copyOptions);
} catch (FileAlreadyExistsException e) {
if (replaceExistentFile)
throw e;
}
if (entry.getUnixMode() != 0 && OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS) {
Files.setPosixFilePermissions(destFile, FileUtils.parsePosixFilePermission(entry.getUnixMode()));
}
}
}
}
if (entryCount == 0 && !"/".equals(subDirectory) && !terminateIfSubDirectoryNotExists) {
throw new NoSuchFileException("Subdirectory " + subDirectory + " does not exist in the zip file.");
}
}
}
@FunctionalInterface
public interface EntryFilter {
boolean accept(ZipArchiveEntry zipArchiveEntry, Path destFile, String relativePath) throws IOException;
}
}
View on GitHub (pinned to 24702dc5a0)