{"record":{"id":"33c58c2177bdc355","repo":"HMCL-dev/HMCL","slug":"curse-forge-modpack-manifest-mod-loader-id-cannot","errorCode":null,"errorMessage":"Curse Forge modpack manifest Mod loader id cannot be blank.","messagePattern":"Curse Forge modpack manifest Mod loader id cannot be blank\\.","errorType":"validation","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseManifestModLoader.java","lineNumber":40,"sourceCode":"@Override\npublic void validate() throws JsonParseException {\n    if (StringUtils.isBlank(id))\n        throw new JsonParseException(\"Curse Forge modpack manifest Mod loader id cannot be blank.\");\n}","sourceCodeStart":22,"sourceCodeEnd":44,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/curse/CurseManifestModLoader.java#L22-L44","documentation":"Validation of a modLoaders entry in a CurseForge manifest: the loader's 'id' must be non-blank. A missing id means HMCL cannot determine which mod loader (forge/fabric) the pack uses, so the manifest is rejected.","triggerScenarios":"Parsing a curse manifest whose minecraft.modLoaders[] entry has an empty/whitespace `id`, then calling validate().","commonSituations":"Manually written manifest with an unfilled modLoaders entry, export tool bug, or JSON key mismatch (\"name\" instead of \"id\") leaving id null.","solutions":["Provide a valid loader id such as \"forge-47.2.0\" or \"fabric-0.15.0\" in each modLoaders entry","Re-export the manifest from the CurseForge app","Check the JSON uses the `id` key expected by the deserializer"],"exampleFix":"// before\n{\"minecraft\":{\"modLoaders\":[{\"id\":\"\",\"primary\":true}]}}\n// after\n{\"minecraft\":{\"modLoaders\":[{\"id\":\"forge-47.2.0\",\"primary\":true}]}}","handlingStrategy":"validation","validationCode":"for (CurseManifestModLoader ml : manifest.getMinecraft().getModLoaders()) { if (isBlank(ml.getId())) throw new IllegalArgumentException(\"modLoader id blank\"); }","typeGuard":"boolean hasLoaderId(CurseManifestModLoader ml) { return ml != null && ml.getId() != null && !ml.getId().isBlank(); }","tryCatchPattern":"try { modLoader.validate(); } catch (JsonParseException e) { log.error(\"Manifest mod loader blank\", e); }","preventionTips":["Fill in modLoaders[].id (e.g. forge-<version>) for every manifest","Avoid hand-editing manifests; re-export instead","Validate the whole manifest with validate() before shipping"],"tags":["curseforge","modpack","validation"],"backgroundTag":"empty-required-field","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}