{"record":{"id":"395e608d94dc5b80","repo":"HMCL-dev/HMCL","slug":"forgeversion-files-cannot-be-null-395e60","errorCode":null,"errorMessage":"ForgeVersion files cannot be null","messagePattern":"ForgeVersion files cannot be null","errorType":"validation","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeVersion.java","lineNumber":88,"sourceCode":"        return version;\n    }\n\n    public int getBuild() {\n        return build;\n    }\n\n    public long getModified() {\n        return modified;\n    }\n\n    public String[][] getFiles() {\n        return files;\n    }\n\n    @Override\n    public void validate() throws JsonParseException {\n        if (files == null)\n            throw new JsonParseException(\"ForgeVersion files cannot be null\");\n        if (version == null)\n            throw new JsonParseException(\"ForgeVersion version cannot be null\");\n        if (mcversion == null)\n            throw new JsonParseException(\"ForgeVersion mcversion cannot be null\");\n    }\n\n}\n","sourceCodeStart":70,"sourceCodeEnd":96,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeVersion.java#L70-L96","documentation":"ForgeVersion.validate() throws this JsonParseException when the parsed Forge install-profile JSON has no 'files' array. HMCL requires the files list to decide which artifacts to download and install for the Forge version; without it the version record is unusable.","triggerScenarios":"Calling validate() on a ForgeVersion deserialized from JSON whose 'files' field is absent or explicitly null — typically a truncated, partially written, or malformed remote Forge JSON feed entry.","commonSituations":"The BMCLAPI/Meta Forge version list returned an incomplete entry, a proxy or cache stripped fields, or the downloaded version JSON was corrupted in transit.","solutions":["Re-fetch the Forge version JSON from the remote repository (delete any local cached copy first).","Check network/proxy integrity — re-download and confirm the JSON contains a non-null 'files' array.","Update HMCL; the feed format may have changed for the Forge version in question."],"exampleFix":"// before: trusting cached JSON\nForgeVersion v = JsonUtils.fromJson(json, ForgeVersion.class);\nv.validate();\n// after: guard before validate\nForgeVersion v = JsonUtils.fromJson(json, ForgeVersion.class);\nif (v == null || v.getFiles() == null) {\n    v = refetchForgeVersion(versionId); // re-download instead of failing\n}\nv.validate();","handlingStrategy":"validation","validationCode":"if (versionJson == null || !versionJson.has(\"files\") || versionJson.get(\"files\").isJsonNull()) refetch();","typeGuard":"boolean hasFiles(ForgeVersion v) { return v != null && v.getFiles() != null; }","tryCatchPattern":"try { v.validate(); } catch (JsonParseException e) { refetchForgeVersion(); }","preventionTips":["Always re-download Forge metadata instead of trusting long-lived caches","Validate JSON shape right after fetch, before use","Use a reputable mirror"],"tags":["json","forge","validation","download"],"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-15T23:17:13.987Z"}