HMCL-dev/HMCL · error · JsonParseException

Json object cannot be null.

Error message

Json object cannot be null.

What it means

JsonUtils.fromNonNullJson deserializes a JSON string and requires a non-null result. This JsonParseException is thrown when the JSON parses to null (e.g. the input string is "null", empty content, or the target maps to a null value).

Solutions

  1. Check the input string is non-empty, valid JSON before calling fromNonNullJson (e.g. !json.isBlank()).
  2. Fix the data source so it emits a real JSON object instead of "null".
  3. If null is legitimately possible, use JsonUtils.fromJson and handle the null result instead.
  4. Initialize the config/store with a default object on first run.

Example fix

// before
T obj = JsonUtils.fromNonNullJson(gson, maybeEmpty, type); // throws on "null"
// after
T obj = maybeEmpty == null || maybeEmpty.isBlank() ? defaultObj
        : JsonUtils.fromNonNullJson(gson, maybeEmpty, type);
Defensive patterns

Strategy: validation

Validate before calling

if (json == null || json.isBlank() || "null".equals(json.trim()))
    return defaultObject; // avoid fromNonNullJson

Type guard

static boolean isNonEmptyJson(String json) {
    return json != null && !json.isBlank() && !"null".equals(json.trim());
}

Try / catch

try {
    return JsonUtils.fromNonNullJson(gson, json, typeToken);
} catch (JsonParseException e) {
    log.warn("Null/empty JSON, using defaults", e);
    return defaultObject;
}

Prevention

When it happens

Trigger: Calling fromNonNullJson(gson, json, type) where json is "null", an empty file/string, or a JSON document whose deserialization yields null.

Common situations: Reading an empty or reset config file, a server returning the literal body "null", or code reading a deleted/never-initialized persisted object.

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

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/JsonUtils.java:464

    /// @throws JsonParseException if the JSON is `null` or cannot be deserialized
    public static <T> T fromNonNullJson(String json, Class<T> classOfT) throws JsonParseException {
        return fromNonNullJson(GSON, json, classOfT);
    }

    /// Deserializes a JSON string into a non-null object described by the given [TypeToken]
    /// using the provided [Gson] instance.  Throws [JsonParseException] if the result would be
    /// `null`.
    ///
    /// @param <T>  the target type
    /// @param gson the [Gson] instance to use
    /// @param json the JSON string to parse
    /// @param type a [TypeToken] describing the target type
    /// @return the deserialized object, never `null`
    /// @throws JsonParseException if the JSON is `null` or cannot be deserialized
    public static <T> T fromNonNullJson(Gson gson, String json, TypeToken<T> type) throws JsonParseException {
        T parsed = fromJson(gson, json, type);
        if (parsed == null)
            throw new JsonParseException("Json object cannot be null.");
        return parsed;
    }

    /// Deserializes a JSON string into a non-null object described by the given [TypeToken]
    /// using [GSON].  Throws [JsonParseException] if the result would be `null`.
    ///
    /// @param <T>  the target type
    /// @param json the JSON string to parse
    /// @param type a [TypeToken] describing the target type
    /// @return the deserialized object, never `null`
    /// @throws JsonParseException if the JSON is `null` or cannot be deserialized
    public static <T> T fromNonNullJson(String json, TypeToken<T> type) throws JsonParseException {
        return fromNonNullJson(GSON, json, type);
    }

    /// Reads and deserializes JSON from an [InputStream] (UTF-8) into a non-null object of the
    /// given class using the provided [Gson] instance.  The stream is closed after reading.
    /// Throws [JsonParseException] if the result would be `null`.

View on GitHub (pinned to 24702dc5a0)