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

  1. Verify the jar contains META-INF/jarjar/metadata.json with a non-empty jars array.
  2. Re-download the mod from its official source; official jar-in-jar builds always declare their nested jars.
  3. If you build the mod, ensure embedded dependencies are declared via jarJar configuration so metadata.json is generated.
  4. 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

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


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)