{"record":{"id":"617da478e200464c","repo":"HMCL-dev/HMCL","slug":"forgeversionroot-mcversion-cannot-be-null","errorCode":null,"errorMessage":"ForgeVersionRoot mcversion cannot be null","messagePattern":"ForgeVersionRoot mcversion cannot be null","errorType":"validation","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeVersionRoot.java","lineNumber":104,"sourceCode":"\n    public Map<String, int[]> getGameVersions() {\n        return mcversion;\n    }\n\n    public Map<String, Integer> getPromos() {\n        return promos;\n    }\n\n    public Map<Integer, ForgeVersion> getNumber() {\n        return number;\n    }\n\n    @Override\n    public void validate() throws JsonParseException {\n        if (number == null)\n            throw new JsonParseException(\"ForgeVersionRoot number cannot be null\");\n        if (mcversion == null)\n            throw new JsonParseException(\"ForgeVersionRoot mcversion cannot be null\");\n    }\n\n}\n","sourceCodeStart":86,"sourceCodeEnd":108,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeVersionRoot.java#L86-L108","documentation":"ForgeVersionRoot.validate() throws this JsonParseException when the 'mcversion' field is null in the parsed Forge root metadata. The Minecraft version binds the Forge build to a game version and is required for HMCL to proceed with installation.","triggerScenarios":"validate() on a ForgeVersionRoot deserialized from JSON missing 'mcversion' — incomplete feed entry, corrupted cache, or upstream schema change.","commonSituations":"Mirror served a partial record, JSON truncated in transit, or a cached entry written by an older HMCL/older metadata format.","solutions":["Clear the cached Forge metadata and re-download from the remote repository.","Check the JSON contains a non-null 'mcversion' matching the target game version.","Switch mirrors or update HMCL."],"exampleFix":"// before\nForgeVersionRoot root = JsonUtils.fromJson(json, ForgeVersionRoot.class);\nroot.validate();\n// after\nForgeVersionRoot root = JsonUtils.fromJson(json, ForgeVersionRoot.class);\nif (root == null || root.getMcversion() == null) {\n    root = refetchForgeVersionRoot(mcVersion);\n}\nroot.validate();","handlingStrategy":"validation","validationCode":"if (rootJson == null || !rootJson.has(\"mcversion\")) refetchForgeRoot();","typeGuard":"boolean hasMcVersion(ForgeVersionRoot r) { return r != null && r.getMcversion() != null; }","tryCatchPattern":"try { root.validate(); } catch (JsonParseException e) { refetchForgeRoot(); }","preventionTips":["Clear cached Forge metadata when switching mirrors","Re-download on any parse anomaly instead of proceeding","Verify the fetched JSON against the schema before caching"],"tags":["json","forge","validation"],"backgroundTag":"schema-validation-failed","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"}