HMCL-dev/HMCL · error · JsonParseException
Theme background field is missing:
Error message
Theme background field is missing:
What it means
ThemeBackground.requireNonBlank throws this JsonParseException when a required source field is absent (null) while constructing a Builtin, Image, or Paint background. It fires when a constructor receives a null value for its mandatory field — e.g. {"type":"image"} with no "path" — because the record's compact constructor delegates to requireNonBlank.
Solutions
- Add the required field for the declared type: "id" for builtin, "path" for image, "paint" for paint
- Use type "default" or "theme_color" instead if no concrete source value exists
- For programmatic construction, pass a non-null string or use the no-arg Builtin() fallback constructor
Example fix
// before
{"type": "image"}
// after
{"type": "image", "path": "assets/bg.png"} Defensive patterns
Strategy: validation
Validate before calling
if (obj.has("type")) {
String t = obj.get("type").getAsString().toUpperCase(Locale.ROOT);
String need = switch (t) { case "IMAGE" -> "path"; case "PAINT" -> "paint"; case "BUILTIN" -> "id"; default -> null; };
if (need != null && !obj.has(need)) throw new IllegalArgumentException("missing field for type " + t + ": " + need);
} Try / catch
try { ThemeBackground.fromJson(obj); } catch (JsonParseException e) { LOG.warning("Background field missing: " + e.getMessage()); } Prevention
- Pair each concrete type with its required value field (image->path, paint->paint, builtin->id)
- Use "default"/"theme_color" when no concrete value is available
- Generate backgrounds via records + toJsonObject() instead of raw JSON
When it happens
Trigger: fromJson on {"type":"builtin"} with no "id" only if code passes null to the Builtin(String) constructor path requiring it — concretely, constructing new Image(null), new Paint(null), or new Builtin with a null id via a code path that requires it, or JSON like {"type":"image"} where path resolves to null for the Image record constructor.
Common situations: Theme manifests where the "type" was set but the matching value field was forgotten ({"type":"image"} with no "path"), or programmatic construction of records with null required arguments.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Theme color source is missing required field:
- Missing protected payload member: nonce
- Theme background without type must contain only one source…
- Unsupported theme background type:
- Theme background field must be a string:
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/1132b89496b75978.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeBackground.java:128
};
}
/// Reads an optional string field.
private static @Nullable String readString(JsonObject object, String field) {
JsonElement element = object.get(field);
if (element == null) {
return null;
}
if (!(element instanceof JsonPrimitive primitive) || !primitive.isString()) {
throw new JsonParseException("Theme background field must be a string: " + field);
}
return primitive.getAsString();
}
/// Returns a required non-blank string value.
private static String requireNonBlank(@Nullable String value, String field) {
if (value == null) {
throw new JsonParseException("Theme background field is missing: " + field);
}
String trimmed = value.trim();
if (trimmed.isEmpty()) {
throw new JsonParseException("Theme background field is blank: " + field);
}
return trimmed;
}
/// A source that delegates to HMCL's launcher default background resolution.
@NotNullByDefault
record Default() implements ThemeBackground {
/// Adds this source to a JSON object.
@Override
public void addToJsonObject(JsonObject object) {
object.addProperty(FIELD_TYPE, "default");
}
}View on GitHub (pinned to 24702dc5a0)