HMCL-dev/HMCL · error · JsonParseException
Theme condition array must contain strings:
Error message
Theme condition array must contain strings:
What it means
In ThemeCondition.readAcceptedValues, every element of a condition's JSON array must be a JSON string primitive. Non-string items (numbers, booleans, objects, nested arrays, nulls) are rejected with this JsonParseException.
Solutions
- Quote every element in the condition array so all are strings, e.g. "os": ["windows"].
- Convert non-string values to their string form in the generator or editor before writing theme JSON.
- Pre-validate the JSON with a schema/walker that requires array items to be string primitives before fromJson.
- Catch JsonParseException around fromJson and surface a precise message pointing at the offending field.
Example fix
// before (theme.json) // "os": ["windows", 10] // after "os": ["windows", "10"]
Defensive patterns
Strategy: validation
Validate before calling
JsonElement v = obj.get("os");
boolean allStrings = v instanceof JsonArray a && !a.isEmpty()
&& java.util.stream.StreamSupport.stream(a.spliterator(), false)
.allMatch(i -> i instanceof JsonPrimitive p && p.isString()); Type guard
static boolean isStringArray(JsonElement e) {
if (!(e instanceof JsonArray a)) return false;
for (JsonElement i : a) {
if (!(i instanceof JsonPrimitive p) || !p.isString()) return false;
}
return true;
} Try / catch
try {
ThemeCondition c = ThemeCondition.fromJson(element);
} catch (JsonParseException e) {
LOG.warning("Malformed condition array: " + e.getMessage());
} Prevention
- Quote all condition array elements as JSON strings
- Never mix numbers or booleans into condition arrays
- Run a JSON schema validation pass on theme files
- Use a theme editor that enforces string-only arrays
When it happens
Trigger: A theme JSON condition array containing e.g. {"os": ["windows", 10]}, {"os": [true]}, or {"os": [["windows"]]} — any element failing the JsonPrimitive/isString check — via ThemeCondition.fromJson.
Common situations: Hand-edited theme files mixing types; authors assuming numeric OS/version codes are valid; generators serializing raw values without quoting.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Theme condition value must be a string or string array:
- Theme condition array is empty:
- Theme condition key is blank
- Empty theme condition value for
- Unsupported brightness condition value:
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/56be84a6260135b8.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeCondition.java:144
object.add(entry.getKey(), array);
}
}
return object;
}
/// Reads one condition field value.
private static Set<String> readAcceptedValues(String key, JsonElement element) throws JsonParseException {
LinkedHashSet<String> values = new LinkedHashSet<>();
if (element instanceof JsonPrimitive primitive && primitive.isString()) {
values.add(normalizeValue(key, primitive.getAsString()));
} else if (element instanceof JsonArray array) {
if (array.isEmpty()) {
throw new JsonParseException("Theme condition array is empty: " + key);
}
for (JsonElement item : array) {
if (!(item instanceof JsonPrimitive primitive) || !primitive.isString()) {
throw new JsonParseException("Theme condition array must contain strings: " + key);
}
values.add(normalizeValue(key, primitive.getAsString()));
}
} else {
throw new JsonParseException("Theme condition value must be a string or string array: " + key);
}
return values;
}
/// Normalizes and validates a condition key.
private static String normalizeKey(String key) {
Objects.requireNonNull(key);
String normalized = key.trim();
if (normalized.isEmpty()) {
throw new JsonParseException("Theme condition key is blank");
}
return normalized;View on GitHub (pinned to 24702dc5a0)