HMCL-dev/HMCL · error · JsonParseException
Theme color source is missing required field:
Error message
Theme color source is missing required field:
What it means
ThemeColorSource.fromJson throws this JsonParseException when the theme color is provided as an object but the required "source" member is absent. The object form exists solely to carry the source discriminator ("default" or "wallpaper"), so an object without it cannot be classified.
Solutions
- Add the "source" field: {"source": "default"} or {"source": "wallpaper"}
- Alternatively use the plain string form "default" instead of the object form
- Serialize sources programmatically via ThemeColorSource.toJsonElement() to guarantee the field
Example fix
// before
"color": {}
// after
"color": {"source": "wallpaper"} Defensive patterns
Strategy: validation
Validate before calling
if (element instanceof JsonObject o && !o.has("source")) throw new IllegalArgumentException("color source object requires \"source\" field"); Type guard
boolean hasSourceField(JsonElement el) {
return !(el instanceof JsonObject o) || o.has("source");
} Try / catch
try { ThemeColorSource.fromJson(el); } catch (JsonParseException e) { LOG.warning("Missing source field: " + e.getMessage()); src = ThemeColorSource.DEFAULT; } Prevention
- Always include "source" in the object form
- Prefer the string form "default" to avoid the object shape entirely
- Build sources via the Default/Custom/Wallpaper records and toJsonElement()
When it happens
Trigger: fromJson on {"seed":"red"}, {}, or {"color":"default"} — any JsonObject without a "source" key in the color-source position of a theme manifest.
Common situations: Theme authors nesting extra color options in the object while forgetting the "source" key, or hand-writing the object form instead of the simpler string form.
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 background field is missing:
- 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/a41116b7753526ae.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeColorSource.java:78
Objects.requireNonNull(element);
if (element instanceof JsonPrimitive primitive && primitive.isString()) {
String value = primitive.getAsString();
if ("default".equals(value.trim().replace('-', '_').toLowerCase(Locale.ROOT))) {
return DEFAULT;
}
@Nullable ThemeColor color = ThemeColor.of(value);
if (color == null) {
throw new JsonParseException("Invalid theme color: " + value);
}
return custom(color);
}
if (!(element instanceof JsonObject object)) {
throw new JsonParseException("Theme color must be a string or object");
}
JsonElement sourceElement = object.get(FIELD_SOURCE);
if (sourceElement == null) {
throw new JsonParseException("Theme color source is missing required field: " + FIELD_SOURCE);
}
if (!(sourceElement instanceof JsonPrimitive sourcePrimitive) || !sourcePrimitive.isString()) {
throw new JsonParseException("Theme color source field must be a string: " + FIELD_SOURCE);
}
String source = sourcePrimitive.getAsString();
String normalized = source.trim().replace('-', '_').toUpperCase(Locale.ROOT);
if ("DEFAULT".equals(normalized)) {
return DEFAULT;
}
if ("WALLPAPER".equals(normalized)) {
return wallpaper();
}
throw new JsonParseException("Unsupported theme color source: " + source);
}
/// Converts this color source to its JSON representation.
///
/// @return the color source JSON valueView on GitHub (pinned to 24702dc5a0)