{"record":{"id":"bbf25984ae9cff81","repo":"HMCL-dev/HMCL","slug":"forgeversion-files-cannot-be-null","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/ForgeBMCLVersionList.java","lineNumber":193,"sourceCode":"        @Nullable\n        public String getModified() {\n            return modified;\n        }\n\n        @NotNull\n        public String getVersion() {\n            return version;\n        }\n\n        @NotNull\n        public List<File> 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        @Immutable\n        public static final class File {\n            private final String format;\n            private final String category;\n            private final String hash;\n\n            public File() {\n                this(\"\", \"\", \"\");\n            }\n\n            public File(String format, String category, String hash) {\n                this.format = format;","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeBMCLVersionList.java#L175-L211","documentation":"ForgeBMCLVersionList's ForgeVersion.validate() throws JsonParseException when the 'files' array parsed from the BMCLAPI Forge version list is null. The library treats a version entry without file entries as unusable metadata.","triggerScenarios":"Parsing a BMCLAPI Forge version list JSON where a version object omits the 'files' field, then invoking validate().","commonSituations":"BMCLAPI mirror returning trimmed/partial data, schema drift in the forge version list API, or hand-crafted test JSON missing 'files'.","solutions":["Fix or regenerate the version-list JSON so each version includes a non-null 'files' array","Catch JsonParseException and skip invalid version entries in the list","Switch to a different Forge mirror/source (e.g. official Forge promotions JSON)"],"exampleFix":"// before\nversion.validate(); // throws if files == null\n// after\ntry {\n    version.validate();\n} catch (JsonParseException e) {\n    LOG.warning(\"Skipping invalid Forge version: \" + e.getMessage());\n}","handlingStrategy":"validation","validationCode":"if (versionObject.get(\"files\") == null || !versionObject.get(\"files\").isJsonArray())\n    throw new JsonParseException(\"ForgeVersion files missing or not an array\");","typeGuard":"static boolean hasFiles(JsonObject entry) {\n    return entry.get(\"files\") instanceof JsonArray;\n}","tryCatchPattern":"try {\n    forgeVersion.validate();\n} catch (JsonParseException e) {\n    LOG.warning(\"Skipping malformed Forge version entry: \" + e.getMessage());\n}","preventionTips":["Validate mirror JSON shape before deserializing into model classes","Use a mirror known to return complete version entries","Cache lists defensively and re-fetch on validation failure"],"tags":["java","forge","json","mirror"],"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"}