HMCL-dev/HMCL · error · JsonParseException

Invalid theme color:

Error message

Invalid theme color: 

What it means

ThemeColorSource.fromJson throws this JsonParseException when the theme color is given as a string (not "default") that ThemeColor.of cannot resolve to a known ThemeColor enum constant. The manifest's color name is not one of the launcher's supported named colors, so the seed color cannot be determined.

Solutions

  1. Replace the string with a valid ThemeColor enum name exactly as defined in the HMCL version in use
  2. Use "default" if the launcher's built-in seed color is acceptable
  3. Check available names via ThemeColor.values()/name() and fix spelling/casing

Example fix

// before
"color": "blurple"
// after
"color": "default"
Defensive patterns

Strategy: validation

Validate before calling

String v = element.getAsString();
if (!"default".equalsIgnoreCase(v) && ThemeColor.of(v) == null) throw new IllegalArgumentException("Unknown theme color: " + v);

Type guard

boolean isKnownThemeColor(String s) {
    return "default".equalsIgnoreCase(s) || ThemeColor.of(s) != null;
}

Try / catch

try { ThemeColorSource.fromJson(el); } catch (JsonParseException e) { LOG.warning("Bad color, falling back: " + e.getMessage()); src = ThemeColorSource.DEFAULT; }

Prevention

When it happens

Trigger: fromJson on a JSON string such as "blurple", "teal-500", or a misspelled name like "deep_purpple" that matches no ThemeColor constant (normalization is trim + '-'->'_' + lowercase for the default check; the color lookup itself is case/name sensitive via ThemeColor.of).

Common situations: Theme authors inventing custom color names, copy-pasting hex codes ("#3b82f6") where an enum name is required, or names from a different HMCL version's color list.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/a79c0e098bb009e4. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeColorSource.java:68

    static ThemeColorSource wallpaper() {
        return new Wallpaper();
    }

    /// Parses a color source from a manifest JSON value.
    ///
    /// @param element the JSON value
    /// @return the parsed color source
    /// @throws JsonParseException if the color source is malformed
    static ThemeColorSource fromJson(JsonElement element) throws JsonParseException {
        Objects.requireNonNull(element);
        if (element instanceof JsonPrimitive primitive && primitive.isString()) {
            String value = primitive.getAsString();
            if ("default".equals(value.trim().replace('-', '_').toLowerCase(Locale.ROOT))) {
                return DEFAULT;
            }
            @Nullable ThemeColor color = ThemeColor.of(value);
            if (color == null) {
                throw new JsonParseException("Invalid theme color: " + value);
            }
            return custom(color);
        }
        if (!(element instanceof JsonObject object)) {
            throw new JsonParseException("Theme color must be a string or object");
        }

        JsonElement sourceElement = object.get(FIELD_SOURCE);
        if (sourceElement == null) {
            throw new JsonParseException("Theme color source is missing required field: " + FIELD_SOURCE);
        }
        if (!(sourceElement instanceof JsonPrimitive sourcePrimitive) || !sourcePrimitive.isString()) {
            throw new JsonParseException("Theme color source field must be a string: " + FIELD_SOURCE);
        }
        String source = sourcePrimitive.getAsString();
        String normalized = source.trim().replace('-', '_').toUpperCase(Locale.ROOT);
        if ("DEFAULT".equals(normalized)) {
            return DEFAULT;

View on GitHub (pinned to 24702dc5a0)