HMCL-dev/HMCL · error · JsonParseException

GameRemoteVersions.versions cannot be null

Error message

GameRemoteVersions.versions cannot be null

What it means

GameRemoteVersions is the deserialized model of Mojang's version manifest (version_manifest_v2.json). Its validate() enforces that the top-level `versions` array parsed from the JSON is present. If the server response lacked the field (or Gson left it null), the data is considered unusable and a JsonParseException is thrown so the version list refresh fails fast instead of producing an empty/broken game version list.

Solutions

  1. Verify the manifest URL is reachable and returns the official version_manifest_v2.json (check with curl or browser).
  2. Clear HMCL's cached version list / download data and refresh the game list again.
  3. Disable HTTP proxies/interception or switch mirror/download provider if a mirror serves incomplete JSON.
  4. Retry later; if Mojang temporarily altered the schema, updating HMCL to a newer build that adapts to the new format fixes it.

Example fix

// Not caller-fixable in code; guard at call site:
try {
    GameRemoteVersions v = JsonUtils.fromJson(json, GameRemoteVersions.class);
    v.validate();
} catch (JsonParseException e) {
    LOG.warning("Version manifest missing 'versions', falling back to cached list", e);
}
Defensive patterns

Strategy: validation

Validate before calling

org.w3c.dom // pre-check the manifest JSON before use
if (!json.contains("\"versions\"")) {
    throw new IllegalStateException("Manifest missing 'versions' — mirror/network problem");
}

Type guard

if (remoteVersions == null || remoteVersions.getVersions() == null) { /* skip/refresh */ }

Try / catch

try { versions.validate(); } catch (JsonParseException e) { LOG.warning("Bad version manifest: " + e.getMessage(), e); /* fall back to cached list */ }

Prevention

When it happens

Trigger: Parsing a Mojang version manifest JSON whose `versions` key is absent or deserialized to null, typically when GameRepository / RemoteVersionList calls GameRemoteVersions.validate() after JsonUtils deserialization.

Common situations: Network middleboxes or mirrors returning truncated/partial JSON; Mojang changing the manifest schema; a proxy or cache serving an error page that still parses as JSON without `versions`; stale/corrupted cached manifest.

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/ff00751143fef022. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameRemoteVersions.java:41

import org.jackhuang.hmcl.util.gson.JsonSerializable;
import org.jackhuang.hmcl.util.gson.Validation;

import java.util.List;

/**
 *
 * @author huangyuhui
 */
@Immutable
@JsonSerializable
public record GameRemoteVersions(
        @SerializedName("versions") List<GameRemoteVersionInfo> versions,
        @SerializedName("latest") GameRemoteLatestVersions latest) implements Validation {

    @Override
    public void validate() throws JsonParseException {
        if (versions == null)
            throw new JsonParseException("GameRemoteVersions.versions cannot be null");
    }
}

View on GitHub (pinned to 24702dc5a0)