HMCL-dev/HMCL · error · JsonParseException
Localized text cannot be empty object
Error message
Localized text cannot be empty object
What it means
LocalizedText.fromJson parses a JSON element into a locale-to-string map. An empty JSON object ({}) carries no text in any language, so the method deliberately rejects it with a JsonParseException rather than producing an empty LocalizedText.
Solutions
- Provide at least one locale key with a string value in the JSON object.
- Use JSON null (or omit the field) if the localized value is intentionally absent, which fromJson maps to null.
- Sanitize input before parsing: convert empty objects to null ahead of the call.
Example fix
// before
{"name": {}}
// after
{"name": {"en": "Default Name"}}
// or, if absent: {"name": null} Defensive patterns
Strategy: validation
Validate before calling
if (el != null && el.isJsonObject() && el.getAsJsonObject().size() == 0) return null; // treat {} as absent Type guard
static boolean isUsableLocalizedText(@Nullable JsonElement el) { return el == null || el.isJsonNull() || (el.isJsonObject() && !el.getAsJsonObject().isEmpty()) || el.isJsonPrimitive(); } Try / catch
try { return LocalizedText.fromJson(el); } catch (JsonParseException e) { log.warn("Bad localized text", e); return null; } Prevention
- Emit null instead of {} for absent localized values.
- Ensure serializers never write empty objects for LocalizedText fields.
- Sanitize external JSON before parsing.
When it happens
Trigger: Calling LocalizedText.fromJson with a JsonElement that is an empty JsonObject — e.g. a field set to {} in config or downloaded JSON data.
Common situations: Serializers or editors emitting {} as a placeholder for an unset localized value; migration scripts wiping translation entries but leaving the empty object.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Theme background field is blank:
- Localized text entry cannot be
- Unexpected json element:
- authlib-injectors.json -> urls cannot be null.
- Missing protected payload member: protection
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/16a559d93a33edc0.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedText.java:60
@JsonSerializable
public final class LocalizedText {
/// Parses a localized text value from a JSON element.
///
/// `null` and JSON `null` are treated as absent text. JSON primitives are converted to plain text with
/// [JsonPrimitive#getAsString()], and JSON objects are parsed as localized values keyed by language tags.
///
/// @param element the JSON element to parse, or `null`
/// @return the parsed localized text, or `null` if `element` is absent
/// @throws JsonParseException if the element is not a primitive or object, the object is empty, or an object entry
/// is not a primitive value
public static @Nullable LocalizedText fromJson(@Nullable JsonElement element) throws JsonParseException {
if (element == null || element instanceof JsonNull)
return null;
if (element instanceof JsonObject jsonObject) {
if (jsonObject.isEmpty()) {
throw new JsonParseException("Localized text cannot be empty object");
}
var map = new LinkedHashMap<String, String>();
jsonObject.asMap().forEach((k, v) -> {
if (v instanceof JsonPrimitive primitive) {
map.put(k, primitive.getAsString());
} else {
throw new JsonParseException("Localized text entry cannot be " + v.getClass());
}
});
return new LocalizedText(map);
}
if (element instanceof JsonPrimitive primitive) {
return new LocalizedText(primitive.getAsString());
}
throw new JsonParseException("Unexpected json element: " + element);View on GitHub (pinned to 24702dc5a0)