{"record":{"id":"ad7df133fc27669d","repo":"HMCL-dev/HMCL","slug":"theme-override-does-not-define-any-appearance-fiel","errorCode":null,"errorMessage":"Theme override does not define any appearance fields","messagePattern":"Theme override does not define any appearance fields","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeOverride.java","lineNumber":45,"sourceCode":"\n/// A conditional appearance patch in a theme.\n///\n/// @param condition  the condition required for this override to apply\n/// @param appearance the appearance fields applied when the condition matches\n@NotNullByDefault\npublic record ThemeOverride(ThemeCondition condition, ThemeAppearance appearance) {\n    /// JSON member name for an override condition.\n    private static final String FIELD_CONDITION = \"condition\";\n\n    /// Creates a conditional theme override.\n    ///\n    /// @param condition  the condition required for this override to apply\n    /// @param appearance the appearance fields applied when the condition matches\n    public ThemeOverride {\n        Objects.requireNonNull(condition);\n        Objects.requireNonNull(appearance);\n        if (appearance.isEmpty()) {\n            throw new IllegalArgumentException(\"Theme override does not define any appearance fields\");\n        }\n    }\n\n    /// Parses a theme override from JSON.\n    ///\n    /// @param element the override object\n    /// @return the parsed override\n    /// @throws JsonParseException if the override is malformed\n    static @Nullable ThemeOverride fromJson(@Nullable JsonElement element) throws JsonParseException {\n        if (element == null || element.isJsonNull())\n            return null;\n\n        if (!(element instanceof JsonObject object)) {\n            throw new JsonParseException(\"Invalid theme override\");\n        }\n\n        JsonElement conditionElement = object.get(FIELD_CONDITION);\n        if (!(conditionElement instanceof JsonObject conditionObject)) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeOverride.java#L27-L63","documentation":"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.","triggerScenarios":"Calling new ThemeOverride(condition, Map.of()) or ThemeOverride.fromJson on a JSON object like {\"when\": {...}} that has no appearance fields (no backgroundColor, foregroundColor, etc.).","commonSituations":"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.","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."],"exampleFix":"// before (theme.json)\n// { \"when\": { \"os\": [\"linux\"] } }\n// after\n// { \"when\": { \"os\": [\"linux\"] }, \"backgroundColor\": \"#1E1E1E\" }","handlingStrategy":"validation","validationCode":"boolean ok = overrideObj.entrySet().stream()\n        .anyMatch(e -> !\"when\".equals(e.getKey()));","typeGuard":"static boolean definesAppearance(com.google.gson.JsonObject o) {\n    return o.entrySet().stream().anyMatch(e -> !\"when\".equals(e.getKey()));\n}","tryCatchPattern":"try {\n    ThemeOverride o = ThemeOverride.fromJson(element);\n} catch (IllegalArgumentException e) {\n    LOG.warning(\"Skipping empty override: \" + e.getMessage());\n}","preventionTips":["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"],"tags":["theme","override","validation","empty-config"],"backgroundTag":"missing-required-config-field","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}