{"record":{"id":"56be84a6260135b8","repo":"HMCL-dev/HMCL","slug":"theme-condition-array-must-contain-strings","errorCode":null,"errorMessage":"Theme condition array must contain strings: ","messagePattern":"Theme condition array must contain strings: ","errorType":"validation","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeCondition.java","lineNumber":144,"sourceCode":"                object.add(entry.getKey(), array);\n            }\n        }\n        return object;\n    }\n\n    /// Reads one condition field value.\n    private static Set<String> readAcceptedValues(String key, JsonElement element) throws JsonParseException {\n        LinkedHashSet<String> values = new LinkedHashSet<>();\n        if (element instanceof JsonPrimitive primitive && primitive.isString()) {\n            values.add(normalizeValue(key, primitive.getAsString()));\n        } else if (element instanceof JsonArray array) {\n            if (array.isEmpty()) {\n                throw new JsonParseException(\"Theme condition array is empty: \" + key);\n            }\n\n            for (JsonElement item : array) {\n                if (!(item instanceof JsonPrimitive primitive) || !primitive.isString()) {\n                    throw new JsonParseException(\"Theme condition array must contain strings: \" + key);\n                }\n                values.add(normalizeValue(key, primitive.getAsString()));\n            }\n        } else {\n            throw new JsonParseException(\"Theme condition value must be a string or string array: \" + key);\n        }\n        return values;\n    }\n\n    /// Normalizes and validates a condition key.\n    private static String normalizeKey(String key) {\n        Objects.requireNonNull(key);\n\n        String normalized = key.trim();\n        if (normalized.isEmpty()) {\n            throw new JsonParseException(\"Theme condition key is blank\");\n        }\n        return normalized;","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeCondition.java#L126-L162","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-edited theme files mixing types; authors assuming numeric OS/version codes are valid; generators serializing raw values without quoting.","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."],"exampleFix":"// before (theme.json)\n// \"os\": [\"windows\", 10]\n// after\n\"os\": [\"windows\", \"10\"]","handlingStrategy":"validation","validationCode":"JsonElement v = obj.get(\"os\");\nboolean allStrings = v instanceof JsonArray a && !a.isEmpty()\n        && java.util.stream.StreamSupport.stream(a.spliterator(), false)\n              .allMatch(i -> i instanceof JsonPrimitive p && p.isString());","typeGuard":"static boolean isStringArray(JsonElement e) {\n    if (!(e instanceof JsonArray a)) return false;\n    for (JsonElement i : a) {\n        if (!(i instanceof JsonPrimitive p) || !p.isString()) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    ThemeCondition c = ThemeCondition.fromJson(element);\n} catch (JsonParseException e) {\n    LOG.warning(\"Malformed condition array: \" + e.getMessage());\n}","preventionTips":["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"],"tags":["json","theme","type-mismatch","condition"],"backgroundTag":"type-mismatch","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}