HMCL-dev/HMCL · error · JsonParseException

Invalid theme override

Error message

Invalid theme override

What it means

fromJson parses a theme override from JSON and requires the element to be a JSON object. If the element is present but is an array, string, number, or boolean, JsonParseException("Invalid theme override") is thrown. This guards the theme pack schema so downstream code can safely read fields like 'condition'.

Solutions

  1. Wrap the override value in a JSON object in the theme pack file
  2. Validate the theme pack JSON structure before loading (element must be an object)
  3. Check for version/schema drift between the theme pack and the loader

Example fix

// before
"overrides": [ { "condition": {}, "darker": 5 } ]
// after
"overrides": { "condition": {}, "darker": 5 }
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidOverride(JsonElement e) {
    return e != null && !e.isJsonNull() && e.isJsonObject();
}

Type guard

static boolean isJsonObject(JsonElement e) {
    return e instanceof JsonObject;
}

Try / catch

try {
    ThemeOverride o = ThemeOverride.fromJson(el);
} catch (JsonParseException e) {
    log.warn("Skipping invalid theme override: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling ThemeOverride.fromJson with a non-null JsonElement that is not a JsonObject (e.g. a JsonArray, JsonPrimitive, or JsonNull is excluded earlier).

Common situations: A theme pack JSON defines an override as a list of overrides instead of an object, quotes the override value as a string, or hand-edits the theme file and changes the structure.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeOverride.java:59

    public ThemeOverride {
        Objects.requireNonNull(condition);
        Objects.requireNonNull(appearance);
        if (appearance.isEmpty()) {
            throw new IllegalArgumentException("Theme override does not define any appearance fields");
        }
    }

    /// Parses a theme override from JSON.
    ///
    /// @param element the override object
    /// @return the parsed override
    /// @throws JsonParseException if the override is malformed
    static @Nullable ThemeOverride fromJson(@Nullable JsonElement element) throws JsonParseException {
        if (element == null || element.isJsonNull())
            return null;

        if (!(element instanceof JsonObject object)) {
            throw new JsonParseException("Invalid theme override");
        }

        JsonElement conditionElement = object.get(FIELD_CONDITION);
        if (!(conditionElement instanceof JsonObject conditionObject)) {
            throw new JsonParseException("Theme override must define an object condition");
        }

        ThemeCondition condition = ThemeCondition.fromJson(conditionObject);
        ThemeAppearance appearance = ThemeAppearance.fromJson(object);
        if (appearance.isEmpty()) {
            throw new JsonParseException("Theme override does not define any appearance fields");
        }
        return new ThemeOverride(condition, appearance);
    }

    /// Returns whether this override matches the given resolution context.
    ///
    /// @param context the context to test

View on GitHub (pinned to 24702dc5a0)