HMCL-dev/HMCL · error · IOException
Missing embedded mods
Error message
Missing embedded mods
What it means
Thrown by ForgeNewModMetadata.fromEmbeddedMod when, after checking both the Embedded-Dependencies-Mod attribute and jarjar/metadata.json, the embeddedModFiles list is empty. This code path is only reached when a jar looks like an embedded-dependency carrier but declares no nested jars, so HMCL has no mod data to extract.
Solutions
- Verify the jar contains META-INF/jarjar/metadata.json with a non-empty jars array.
- Re-download the mod from its official source; official jar-in-jar builds always declare their nested jars.
- If you build the mod, ensure embedded dependencies are declared via jarJar configuration so metadata.json is generated.
- If the jar intentionally has no embedded mods, it should not take the embedded path — check its mods.toml is intact.
Example fix
// before (metadata.json)
{ "jars": [] }
// after
{ "jars": [ { "identifier": { "group": "com.example", "artifact": "dep" }, "version": "1.0.0", "path": "META-INF/jarjar/dep-1.0.0.jar" } ] } Defensive patterns
Strategy: validation
Validate before calling
ZipArchiveEntry jarjar = tree.getEntry("META-INF/jarjar/metadata.json");
if (jarjar == null || tree.getChildren("META-INF/jarjar").isEmpty()) {
// no embedded jars declared; this jar will fail the embedded path
LOG.warning("No embedded mods declared in " + modFile);
} Try / catch
try {
LocalModFile mod = ForgeNewModMetadata.fromFile(modManager, modFile, tree, type);
} catch (IOException e) {
if ("Missing embedded mods".equals(e.getMessage())) {
// treat the jar as having no embedded dependencies and skip
}
} Prevention
- Ensure jarJar builds declare at least one nested jar
- Verify META-INF/jarjar contains both metadata.json and the listed jar files
- Do not strip META-INF/jarjar contents when repackaging
When it happens
Trigger: fromFile -> fromEmbeddedMod on a jar that has neither an Embedded-Dependencies-Mod manifest attribute nor a jarjar/metadata.json with a non-empty jars array (or the metadata.json was absent), leaving embeddedModFiles empty.
Common situations: A repackaged Forge jar whose jarjar metadata was stripped; a jar with an empty jars array in metadata.json; a mod carrier jar missing both manifest attribute and metadata.json.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- "Invalid metadata file: " + jarInJarMetadata
- "File " + modFile + " is not a Forge 1.13+ or NeoForge mod."
- "Mod " + modFile + " ` ` is…
- "Missing MANIFEST.MF in file " + modFile
- Unknown type of file
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/ecf188fad07c6ba2.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/addon/meta/ForgeNewModMetadata.java:295
if (metadata == null)
throw new IOException("Invalid metadata file: " + jarInJarMetadata);
metadata.validate();
embeddedModFiles = new ArrayList<>();
for (EmbeddedJarMetadata jar : metadata.jars) {
ZipArchiveEntry path = tree.getEntry(jar.path);
if (path != null) {
embeddedModFiles.add(path);
} else {
LOG.warning("Missing embedded-dependencies-mod: " + jar.path);
}
}
}
}
if (embeddedModFiles.isEmpty()) {
throw new IOException("Missing embedded mods");
}
Path tempFile = Files.createTempFile("hmcl-", ".zip");
try {
for (ZipArchiveEntry embeddedModFile : embeddedModFiles) {
tree.extractTo(embeddedModFile, tempFile);
try (ZipFileTree embeddedTree = CompressingUtils.openZipTree(tempFile)) {
return fromFile(modManager, modFile, embeddedTree, modLoaderType);
} catch (Exception ignored) {
}
}
} finally {
Files.deleteIfExists(tempFile);
}
throw new IOException();
}
View on GitHub (pinned to 24702dc5a0)