HMCL-dev/HMCL · error · IOException

"Mod " + modFile + " `litemod.json` is malformed."

Error message

"Mod " + modFile + " `litemod.json` is malformed."

What it means

After locating `litemod.json`, LiteModMetadata.fromFile deserializes it with JsonUtils.fromJsonFully. A null result (JSON `null`, blank stream, or lenient parse yielding nothing) triggers this IOException because no LiteLoader metadata exists.

Solutions

  1. Verify `litemod.json` content is a complete JSON object with name/version/gameVersion
  2. Re-download or rebuild the mod
  3. Remove the broken file from the mods folder

Example fix

// before (empty litemod.json)

// after
{ "name": "Example", "mcversion": "1.12.2", "version": "1.0" }
Defensive patterns

Strategy: try-catch

Validate before calling

var e = tree.getEntry("litemod.json");
String s = new String(tree.getInputStream(e).readAllBytes(), StandardCharsets.UTF_8);
if (s.isBlank() || s.trim().equals("null")) throw new IllegalStateException("litemod.json blank");

Try / catch

try {
    LiteModMetadata.fromFile(modManager, modFile, tree);
} catch (IOException | JsonParseException e) {
    log.warn("Malformed litemod.json in " + modFile, e);
}

Prevention

When it happens

Trigger: Calling LiteModMetadata.fromFile on an archive whose `litemod.json` is empty, contains only `null`, or otherwise deserializes to null.

Common situations: Truncated/corrupted mod downloads; hand-created `litemod.json` left blank; packaging step that wrote a zero-byte entry.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/addon/meta/LiteModMetadata.java:119

    public String getModpackVersion() {
        return modpackVersion;
    }

    public String getCheckUpdateUrl() {
        return checkUpdateUrl;
    }

    public String getUpdateURI() {
        return updateURI;
    }

    public static LocalModFile fromFile(ModManager modManager, Path modFile, ZipFileTree tree) throws IOException, JsonParseException {
        ZipArchiveEntry entry = tree.getEntry("litemod.json");
        if (entry == null)
            throw new IOException("File " + modFile + " is not a LiteLoader mod.");
        LiteModMetadata metadata = JsonUtils.fromJsonFully(tree.getInputStream(entry), LiteModMetadata.class);
        if (metadata == null)
            throw new IOException("Mod " + modFile + " `litemod.json` is malformed.");
        return new LocalModFile(modManager, modManager.getLocalMod(metadata.getName(), ModLoaderType.LITE_LOADER), modFile, metadata.getName(), new LocalAddonFile.Description(metadata.getDescription()), metadata.getAuthor(),
                metadata.getVersion(), metadata.getGameVersion(), metadata.getUpdateURI(), "");
    }

}

View on GitHub (pinned to 24702dc5a0)