{"record":{"id":"4ab067e88fe3fa0e","repo":"HMCL-dev/HMCL","slug":"missing-manifest-mf-in-file-modfile","errorCode":null,"errorMessage":"\"Missing MANIFEST.MF in file \" + modFile","messagePattern":"\"Missing MANIFEST\\.MF in file \" \\+ modFile","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/addon/meta/ForgeNewModMetadata.java","lineNumber":256,"sourceCode":"            } catch (IOException e) {\n                LOG.warning(\"Failed to parse MANIFEST.MF in file \" + modFile);\n            }\n        }\n\n        ModLoaderType type = analyzeLoader(tomlParseResult, mod.getModId(), modLoaderType);\n\n        String logoPath = StringUtils.isNotBlank(mod.getLogoFile()) ? mod.getLogoFile() : metadata.getLogoFile();\n\n        return new LocalModFile(modManager, modManager.getLocalMod(mod.getModId(), type), modFile, mod.getDisplayName(), new LocalAddonFile.Description(mod.getDescription()),\n                mod.getAuthors(), jarVersion == null ? mod.getVersion() : mod.getVersion().replace(\"${file.jarVersion}\", jarVersion), \"\",\n                mod.getDisplayURL(),\n                logoPath);\n    }\n\n    private static LocalModFile fromEmbeddedMod(ModManager modManager, Path modFile, ZipFileTree tree, ModLoaderType modLoaderType) throws IOException {\n        ZipArchiveEntry manifestFile = tree.getEntry(\"META-INF/MANIFEST.MF\");\n        if (manifestFile == null)\n            throw new IOException(\"Missing MANIFEST.MF in file \" + modFile);\n\n        Manifest manifest;\n        try (InputStream input = tree.getInputStream(manifestFile)) {\n            manifest = new Manifest(input);\n        }\n\n        List<ZipArchiveEntry> embeddedModFiles = List.of();\n\n        String embeddedDependenciesMod = manifest.getMainAttributes().getValue(\"Embedded-Dependencies-Mod\");\n        if (embeddedDependenciesMod != null) {\n            ZipArchiveEntry embeddedModFile = tree.getEntry(embeddedDependenciesMod);\n            if (embeddedModFile == null) {\n                LOG.warning(\"Missing embedded-dependencies-mod: \" + embeddedDependenciesMod);\n                throw new IOException();\n            }\n            embeddedModFiles = List.of(embeddedModFile);\n        } else {\n            ZipArchiveEntry jarInJarMetadata = tree.getEntry(\"META-INF/jarjar/metadata.json\");","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/addon/meta/ForgeNewModMetadata.java#L238-L274","documentation":"Thrown by ForgeNewModMetadata.fromEmbeddedMod when the jar has no META-INF/MANIFEST.MF entry. The embedded-mod identification path builds metadata from the jar manifest attributes, so without a manifest it cannot proceed and gives up so fromFile can fall through to the toml path or fail outright.","triggerScenarios":"fromFile -> fromEmbeddedMod on a jar where tree.getEntry(\"META-INF/MANIFEST.MF\") returns null, and the embedded-mod identification cannot continue.","commonSituations":"A jar repackaged with a tool that dropped or relocated META-INF/MANIFEST.MF; jars built without a jar manifest; non-mod jars placed in the mods directory.","solutions":["Check that META-INF/MANIFEST.MF exists at the archive root of the jar.","Re-download the mod — official builds always ship a manifest.","If repackaging, use Gradle's jar task or preserve META-INF/MANIFEST.MF during repack.","If the jar also lacks mods.toml, it is not a Forge 1.13+ mod; use the appropriate loader parser."],"exampleFix":"// before\nLocalModFile mod = ForgeNewModMetadata.fromFile(modManager, strippedJar, tree, type); // fails: no MANIFEST.MF\n// after\nif (tree.getEntry(\"META-INF/MANIFEST.MF\") == null) {\n    throw new IllegalArgumentException(strippedJar + \" lacks META-INF/MANIFEST.MF; re-download or repackage preserving the manifest\");\n}\nLocalModFile mod = ForgeNewModMetadata.fromFile(modManager, strippedJar, tree, type);","handlingStrategy":"validation","validationCode":"if (tree.getEntry(\"META-INF/MANIFEST.MF\") == null) {\n    throw new IllegalArgumentException(modFile + \" has no jar manifest; cannot parse embedded mod metadata\");\n}","typeGuard":"boolean hasManifest(ZipFileTree tree) { return tree.getEntry(\"META-INF/MANIFEST.MF\") != null; }","tryCatchPattern":"try {\n    LocalModFile mod = ForgeNewModMetadata.fromFile(modManager, modFile, tree, type);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"MANIFEST.MF\")) {\n        // repack preserving META-INF/MANIFEST.MF or skip the jar\n    }\n}","preventionTips":["Always preserve META-INF/MANIFEST.MF when repackaging jars","Use standard build tools (Gradle jar task) that emit manifests","Verify archive layout with unzip -l after any repack"],"tags":["minecraft","forge","manifest","jar"],"backgroundTag":"resource-not-found","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}