HMCL-dev/HMCL · error · IllegalArgumentException
Theme override does not define any appearance fields
Error message
Theme override does not define any appearance fields
What it means
A ThemeOverride exists to apply appearance fields when its condition matches. The compact constructor requires a non-empty appearance map; an override that changes nothing is a config error, so the constructor throws IllegalArgumentException.
Solutions
- Add at least one appearance field to the override, e.g. "backgroundColor": "#RRGGBB".
- Delete the empty override object from the theme JSON entirely.
- Validate override objects before parsing: require at least one non-"when" key.
- If overrides are built programmatically, skip overrides whose appearance map is empty.
Example fix
// before (theme.json)
// { "when": { "os": ["linux"] } }
// after
// { "when": { "os": ["linux"] }, "backgroundColor": "#1E1E1E" } Defensive patterns
Strategy: validation
Validate before calling
boolean ok = overrideObj.entrySet().stream()
.anyMatch(e -> !"when".equals(e.getKey())); Type guard
static boolean definesAppearance(com.google.gson.JsonObject o) {
return o.entrySet().stream().anyMatch(e -> !"when".equals(e.getKey()));
} Try / catch
try {
ThemeOverride o = ThemeOverride.fromJson(element);
} catch (IllegalArgumentException e) {
LOG.warning("Skipping empty override: " + e.getMessage());
} Prevention
- Every override must set at least one appearance field besides "when"
- Delete override objects that no longer change anything
- Validate override objects against a schema requiring appearance keys
- When building overrides programmatically, skip empty appearance maps
When it happens
Trigger: Calling new ThemeOverride(condition, Map.of()) or ThemeOverride.fromJson on a JSON object like {"when": {...}} that has no appearance fields (no backgroundColor, foregroundColor, etc.).
Common situations: Hand-edited theme files where all override fields were deleted but the override object kept; generators emitting empty override stubs; refactors that moved fields out of an override.
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 condition field has no accepted values:
- accountID is missing
- acTL chunk length must be
- /assets/
- authlib-injectors.json -> urls cannot be null.
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/ad7df133fc27669d.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeOverride.java:45
/// A conditional appearance patch in a theme.
///
/// @param condition the condition required for this override to apply
/// @param appearance the appearance fields applied when the condition matches
@NotNullByDefault
public record ThemeOverride(ThemeCondition condition, ThemeAppearance appearance) {
/// JSON member name for an override condition.
private static final String FIELD_CONDITION = "condition";
/// Creates a conditional theme override.
///
/// @param condition the condition required for this override to apply
/// @param appearance the appearance fields applied when the condition matches
public ThemeOverride {
Objects.requireNonNull(condition);
Objects.requireNonNull(appearance);
if (appearance.isEmpty()) {
throw new IllegalArgumentException("Theme override does not define any appearance fields");
}
}
/// Parses a theme override from JSON.
///
/// @param element the override object
/// @return the parsed override
/// @throws JsonParseException if the override is malformed
static @Nullable ThemeOverride fromJson(@Nullable JsonElement element) throws JsonParseException {
if (element == null || element.isJsonNull())
return null;
if (!(element instanceof JsonObject object)) {
throw new JsonParseException("Invalid theme override");
}
JsonElement conditionElement = object.get(FIELD_CONDITION);
if (!(conditionElement instanceof JsonObject conditionObject)) {View on GitHub (pinned to 24702dc5a0)