{"record":{"id":"205562a9ff13eaad","repo":"HMCL-dev/HMCL","slug":"unsupported-theme-color-source","errorCode":null,"errorMessage":"Unsupported theme color source: ","messagePattern":"Unsupported theme color source: ","errorType":"validation","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeColorSource.java","lineNumber":91,"sourceCode":"            throw new JsonParseException(\"Theme color must be a string or object\");\n        }\n\n        JsonElement sourceElement = object.get(FIELD_SOURCE);\n        if (sourceElement == null) {\n            throw new JsonParseException(\"Theme color source is missing required field: \" + FIELD_SOURCE);\n        }\n        if (!(sourceElement instanceof JsonPrimitive sourcePrimitive) || !sourcePrimitive.isString()) {\n            throw new JsonParseException(\"Theme color source field must be a string: \" + FIELD_SOURCE);\n        }\n        String source = sourcePrimitive.getAsString();\n        String normalized = source.trim().replace('-', '_').toUpperCase(Locale.ROOT);\n        if (\"DEFAULT\".equals(normalized)) {\n            return DEFAULT;\n        }\n        if (\"WALLPAPER\".equals(normalized)) {\n            return wallpaper();\n        }\n        throw new JsonParseException(\"Unsupported theme color source: \" + source);\n    }\n\n    /// Converts this color source to its JSON representation.\n    ///\n    /// @return the color source JSON value\n    JsonElement toJsonElement();\n\n    /// Returns the best available color without accessing wallpaper pixels.\n    ///\n    /// @return the custom color or launcher default color\n    ThemeColor resolveFallback();\n\n    /// The launcher default color seed.\n    @NotNullByDefault\n    record Default() implements ThemeColorSource {\n        /// Creates a default color source.\n        public Default {\n        }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeColorSource.java#L73-L109","documentation":"ThemeColorSource.fromJson parses a JSON string into a ThemeColorSource enum-like value. Only the normalized names \"default\" and \"wallpaper\" are accepted; anything else is rejected with this JsonParseException so malformed theme files fail fast at parse time.","triggerScenarios":"Calling ThemeColorSource.fromJson with a string that is not (case-insensitively, trimmed) \"DEFAULT\" or \"WALLPAPER\", e.g. fromJson(\"image\"), fromJson(\"solid\"), or a misspelled \"wallpapper\" in a theme JSON's color-source field.","commonSituations":"Hand-edited theme JSON files using an invented source name; themes ported from other launchers with different vocabularies; typos after manual editing; old themes written for a launcher version whose accepted set changed.","solutions":["Change the theme JSON color-source value to exactly \"DEFAULT\" or \"WALLPAPER\" (case-insensitive).","Check available sources via ThemeColorSource.DEFAULT and ThemeColorSource.wallpaper() and pick one of those.","Wrap fromJson in a try-catch for JsonParseException and fall back to ThemeColorSource.DEFAULT for untrusted theme files.","Update the theme file if it was authored for an older/newer launcher version with a different source vocabulary."],"exampleFix":"// before\nJsonElement el = theme.get(\"colorSource\");\nThemeColorSource src = ThemeColorSource.fromJson(el.getAsString()); // \"image\" -> throws\n// after\nString raw = el.getAsString();\nThemeColorSource src = \"image\".equalsIgnoreCase(raw)\n        ? ThemeColorSource.DEFAULT // unsupported name: use fallback\n        : ThemeColorSource.fromJson(raw);","handlingStrategy":"try-catch","validationCode":"boolean ok = raw != null && (raw.trim().equalsIgnoreCase(\"DEFAULT\") || raw.trim().equalsIgnoreCase(\"WALLPAPER\"));","typeGuard":"static boolean isKnownColorSource(String s) {\n    return s != null && (s.trim().equalsIgnoreCase(\"DEFAULT\") || s.trim().equalsIgnoreCase(\"WALLPAPER\"));\n}","tryCatchPattern":"ThemeColorSource src;\ntry {\n    src = ThemeColorSource.fromJson(raw);\n} catch (JsonParseException e) {\n    LOG.warning(\"Unknown color source '\" + raw + \"', using DEFAULT\");\n    src = ThemeColorSource.DEFAULT;\n}","preventionTips":["Only use the source names exposed by ThemeColorSource constants/factories","Validate theme JSON against a schema listing allowed color-source values","Case-insensitively check the value before calling fromJson","For untrusted theme files, always wrap fromJson and fall back to DEFAULT"],"tags":["json","theme","enum-parsing","config"],"backgroundTag":"invalid-enum-value","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}