{"record":{"id":"0d568dbbb73c7518","repo":"HMCL-dev/HMCL","slug":"file-modfile-is-not-a-forge-mod","errorCode":null,"errorMessage":"\"File \" + modFile + \" is not a Forge mod.\"","messagePattern":"\"File \" \\+ modFile \\+ \" is not a Forge mod\\.\"","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/addon/meta/ForgeOldModMetadata.java","lineNumber":130,"sourceCode":"        return updateUrl;\n    }\n\n    public String getCredits() {\n        return credits;\n    }\n\n    public String[] getAuthorList() {\n        return authorList;\n    }\n\n    public String[] getAuthors() {\n        return authors;\n    }\n\n    public static LocalModFile fromFile(ModManager modManager, Path modFile, ZipFileTree tree) throws IOException, JsonParseException {\n        ZipArchiveEntry mcmod = tree.getEntry(\"mcmod.info\");\n        if (mcmod == null)\n            throw new IOException(\"File \" + modFile + \" is not a Forge mod.\");\n\n        List<ForgeOldModMetadata> modList;\n\n        try (var reader = tree.getBufferedReader(mcmod);\n             var jsonReader = new JsonReader(reader)) {\n            JsonToken firstToken = jsonReader.peek();\n\n            if (firstToken == JsonToken.BEGIN_ARRAY)\n                modList = JsonUtils.GSON.fromJson(jsonReader, listTypeOf(ForgeOldModMetadata.class));\n            else if (firstToken == JsonToken.BEGIN_OBJECT) {\n                ForgeOldModMetadataLst list = JsonUtils.GSON.fromJson(jsonReader, ForgeOldModMetadataLst.class);\n                if (list == null)\n                    throw new IOException(\"Mod \" + modFile + \" `mcmod.info` is malformed\");\n                modList = list.modList();\n            } else {\n                throw new JsonParseException(\"Unexpected first token: \" + firstToken);\n            }\n        }","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/addon/meta/ForgeOldModMetadata.java#L112-L148","documentation":"Thrown by ForgeOldModMetadata.fromFile when the jar contains no mcmod.info entry. HMCL identifies legacy Forge (1.12 and older) mods by parsing mcmod.info at the jar root; without it the jar cannot be recognized as an old Forge mod.","triggerScenarios":"Calling ForgeOldModMetadata.fromFile(modManager, modFile, tree) on a jar whose ZipFileTree has no entry named 'mcmod.info'.","commonSituations":"Pointing the legacy parser at a 1.13+ Forge/NeoForge mod (uses mods.toml) or a Fabric mod (fabric.mod.json); a repackaged jar where mcmod.info was deleted; non-mod library jars in the mods folder.","solutions":["Verify the jar contains mcmod.info at its root (unzip -l mod.jar | grep mcmod.info).","For Forge 1.13+/NeoForge jars, use ForgeNewModMetadata.fromFile/fromNeoForgeFile instead.","Re-download the mod; official legacy builds always include mcmod.info.","If repackaging a legacy mod, keep mcmod.info at the archive root."],"exampleFix":"// before\nLocalModFile mod = ForgeOldModMetadata.fromFile(modManager, modernForgeJar, tree); // throws: no mcmod.info\n// after\nif (tree.getEntry(\"mcmod.info\") == null && tree.getEntry(\"META-INF/mods.toml\") != null) {\n    LocalModFile mod = ForgeNewModMetadata.fromFile(modManager, modernForgeJar, tree, ModLoaderType.FORGE);\n}","handlingStrategy":"validation","validationCode":"if (tree.getEntry(\"mcmod.info\") == null) {\n    // legacy Forge parser will throw; route elsewhere\n    return null;\n}","typeGuard":"boolean isLegacyForgeMod(ZipFileTree tree) { return tree.getEntry(\"mcmod.info\") != null; }","tryCatchPattern":"try {\n    LocalModFile mod = ForgeOldModMetadata.fromFile(modManager, modFile, tree);\n} catch (IOException e) {\n    LOG.warning(\"Skipping jar without mcmod.info: \" + modFile);\n}","preventionTips":["Detect loader by entry presence: mcmod.info (legacy Forge), mods.toml (1.13+ Forge), fabric.mod.json (Fabric)","Preserve mcmod.info at the archive root when repackaging legacy mods","Re-download legacy mods from official sources rather than hand-repackaging"],"tags":["minecraft","forge-legacy","mod-loader","file-not-found"],"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"}