{"record":{"id":"bf4552f5ff2e2b1f","repo":"HMCL-dev/HMCL","slug":"theme-condition-key-is-blank","errorCode":null,"errorMessage":"Theme condition key is blank","messagePattern":"Theme condition key is blank","errorType":"validation","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeCondition.java","lineNumber":160,"sourceCode":"            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;\n    }\n\n    /// Normalizes and validates one condition value.\n    private static String normalizeValue(String key, String value) {\n        Objects.requireNonNull(key);\n        Objects.requireNonNull(value);\n\n        String trimmed = value.trim();\n        if (trimmed.isEmpty()) {\n            throw new JsonParseException(\"Empty theme condition value for \" + key);\n        }\n        String normalized = trimmed.toLowerCase(Locale.ROOT);\n\n        return switch (key) {\n            case KEY_BRIGHTNESS -> switch (normalized) {\n                    case \"light\", \"dark\" -> normalized;","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeCondition.java#L142-L178","documentation":"Fires in ThemeCondition.normalizeKey() when a condition object's key is missing or blank. Condition keys drive which theme variant is applied (e.g. system or version conditions), so an unnamed key cannot be normalized or matched and the whole theme manifest fails parsing. The input at fault is a condition entry with an empty or absent key.","triggerScenarios":"Building a ThemeCondition from a map with a key like \"\" or \"   \", or from JSON object entries with whitespace-only names — normalizeKey runs on every entry during fromJson.","commonSituations":"Hand-edited theme JSON with an unnamed condition field; string concatenation producing empty keys; generators emitting placeholder keys that collapse to empty after trimming.","solutions":["Give the condition field a real key, e.g. \"os\", \"language\", or \"brightness\".","Delete the blank-keyed entry from the theme JSON or requirements map.","Trim/default keys before constructing the map; skip entries whose trimmed key is empty.","Catch JsonParseException around fromJson and report the malformed condition entry to the user."],"exampleFix":"// before (theme.json)\n// \"conditions\": { \"\": [\"windows\"] }\n// after\n\"conditions\": { \"os\": [\"windows\"] }","handlingStrategy":"validation","validationCode":"boolean ok = key != null && !key.trim().isEmpty();","typeGuard":"static boolean isNotBlankKey(String k) {\n    return k != null && !k.trim().isEmpty();\n}","tryCatchPattern":"try {\n    ThemeCondition c = ThemeCondition.fromJson(element);\n} catch (JsonParseException e) {\n    LOG.warning(\"Theme has a blank condition key: \" + e.getMessage());\n}","preventionTips":["Always name condition fields with a real key (os, language, brightness)","Remove empty/whitespace object keys from theme JSON","Trim keys before building conditions programmatically","Validate theme JSON key names against the known condition set"],"tags":["json","theme","condition","blank-key"],"backgroundTag":"empty-required-field","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"}