HMCL-dev/HMCL · error · JsonParseException

Unsupported theme color source:

Error message

Unsupported theme color source: 

What it means

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.

Solutions

  1. Change the theme JSON color-source value to exactly "DEFAULT" or "WALLPAPER" (case-insensitive).
  2. Check available sources via ThemeColorSource.DEFAULT and ThemeColorSource.wallpaper() and pick one of those.
  3. Wrap fromJson in a try-catch for JsonParseException and fall back to ThemeColorSource.DEFAULT for untrusted theme files.
  4. Update the theme file if it was authored for an older/newer launcher version with a different source vocabulary.

Example fix

// before
JsonElement el = theme.get("colorSource");
ThemeColorSource src = ThemeColorSource.fromJson(el.getAsString()); // "image" -> throws
// after
String raw = el.getAsString();
ThemeColorSource src = "image".equalsIgnoreCase(raw)
        ? ThemeColorSource.DEFAULT // unsupported name: use fallback
        : ThemeColorSource.fromJson(raw);
Defensive patterns

Strategy: try-catch

Validate before calling

boolean ok = raw != null && (raw.trim().equalsIgnoreCase("DEFAULT") || raw.trim().equalsIgnoreCase("WALLPAPER"));

Type guard

static boolean isKnownColorSource(String s) {
    return s != null && (s.trim().equalsIgnoreCase("DEFAULT") || s.trim().equalsIgnoreCase("WALLPAPER"));
}

Try / catch

ThemeColorSource src;
try {
    src = ThemeColorSource.fromJson(raw);
} catch (JsonParseException e) {
    LOG.warning("Unknown color source '" + raw + "', using DEFAULT");
    src = ThemeColorSource.DEFAULT;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/205562a9ff13eaad. Report an issue: GitHub.

Appendix: source

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

            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;
        }
        if ("WALLPAPER".equals(normalized)) {
            return wallpaper();
        }
        throw new JsonParseException("Unsupported theme color source: " + source);
    }

    /// Converts this color source to its JSON representation.
    ///
    /// @return the color source JSON value
    JsonElement toJsonElement();

    /// Returns the best available color without accessing wallpaper pixels.
    ///
    /// @return the custom color or launcher default color
    ThemeColor resolveFallback();

    /// The launcher default color seed.
    @NotNullByDefault
    record Default() implements ThemeColorSource {
        /// Creates a default color source.
        public Default {
        }

View on GitHub (pinned to 24702dc5a0)