HMCL-dev/HMCL · error · JsonParseException

ForgeNewInstallProfile is malformed

Error message

ForgeNewInstallProfile is malformed

What it means

ForgeNewInstallProfile.validate() throws JsonParseException when the parsed install_profile.json is missing one of its required fields (minecraft, json, or version). HMCL uses this check to reject installer profiles that do not conform to the Forge 'new' install_profile spec, since without these fields the installation cannot proceed. It is thrown during JSON deserialization validation, before any installation work begins.

Solutions

  1. Re-download the Forge installer from the official maven (files.minecraftforge.net / maven.minecraftforge.net) and verify the JAR is a complete download
  2. Open the installer JAR and confirm install_profile.json contains non-null minecraft, json, and version fields
  3. Ensure the correct ForgeInstallTask variant is used for the installer format (old installers need the legacy task, not ForgeNewInstallTask)
  4. Verify the file passed as 'installer' to ForgeNewInstallTask is actually the Forge installer JAR, not another artifact

Example fix

// before: passing a truncated installer
new ForgeNewInstallTask(dependencyManager, manifest, minecraftJar, version, Paths.get("forge-installer-partial.jar"));
// after: verify installer integrity first
Path installer = Paths.get("forge-installer.jar");
try (JarFile jf = new JarFile(installer.toFile())) {
    if (jf.getEntry("install_profile.json") == null) throw new IOException("Not a valid Forge installer");
}
new ForgeNewInstallTask(dependencyManager, manifest, minecraftJar, version, installer);
Defensive patterns

Strategy: validation

Validate before calling

// Before running ForgeNewInstallTask, inspect the profile inside the installer
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
    String raw = Files.readString(fs.getPath("install_profile.json"));
    JsonObject o = JsonParser.parseString(raw).getAsJsonObject();
    if (o.get("minecraft") == null || o.get("json") == null || o.get("version") == null)
        throw new IOException("Installer profile missing required fields");
}

Try / catch

try {
    new ForgeNewInstallTask(dm, manifest, mcJar, version, installer).run();
} catch (JsonParseException e) {
    // re-download installer / fall back to legacy install task
}

Prevention

When it happens

Trigger: Calling ForgeNewInstallTask.preExecute() on a Forge installer whose install_profile.json lacks the 'minecraft', 'json', or 'version' keys, or where Gson deserialized them as null (e.g. wrong JSON shape, truncated/corrupted installer, or an old-format profile fed to the new-profile parser).

Common situations: Using a corrupted or partially downloaded Forge/NeoForge installer JAR; pointing the task at an installer that actually uses the legacy install_profile format; a Forge installer version whose profile schema changed; hand-crafted or modified install_profile.json.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/8909d772be54f504. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallProfile.java:123

        return processors.stream().filter(p -> p.isSide("client")).collect(Collectors.toList());
    }

    /**
     * Data for processors.
     *
     * @return a mutable data map for processors.
     */
    public Map<String, String> getData() {
        if (data == null)
            return new HashMap<>();

        return data.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getClient()));
    }

    @Override
    public void validate() throws JsonParseException, TolerableValidationException {
        if (minecraft == null || json == null || version == null)
            throw new JsonParseException("ForgeNewInstallProfile is malformed");
    }

    public static class Processor implements Validation {
        private final List<String> sides;
        private final Artifact jar;
        private final List<Artifact> classpath;
        private final List<String> args;
        private final Map<String, String> outputs;

        public Processor(List<String> sides, Artifact jar, List<Artifact> classpath, List<String> args, Map<String, String> outputs) {
            this.sides = sides;
            this.jar = jar;
            this.classpath = classpath;
            this.args = args;
            this.outputs = outputs;
        }

        /**

View on GitHub (pinned to 24702dc5a0)