HMCL-dev/HMCL · error · JsonParseException

Theme-pack theme must be an object

Error message

Theme-pack theme must be an object

What it means

Thrown by readThemes when the manifest's "theme" key exists but its value is not a JSON object. A single-theme declaration must be an object holding the theme fields; strings, numbers, booleans, or arrays are rejected.

Solutions

  1. Make "theme" a JSON object with the theme fields: { "theme": { "id": "main", ... } }.
  2. If you meant to reference an external theme by id, instead inline the full theme definition — string references are not supported.
  3. Validate the JSON structure (e.g. with a JSON linter) to catch brace/quote mistakes that turn the object into another type.

Example fix

// before
{ "theme": "mytheme" }
// after
{ "theme": { "id": "mytheme", "backgroundColor": "#1e1f22" } }
Defensive patterns

Strategy: type-guard

Validate before calling

JsonElement t = manifest.get("theme");
if (t != null && !(t instanceof JsonObject)) {
    throw new IllegalArgumentException("'theme' must be a JSON object, got: " + t.getClass().getSimpleName());
}

Type guard

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

Try / catch

try {
    ThemePackManifest.read(json);
} catch (JsonParseException e) {
    if (e.getMessage().equals("Theme-pack theme must be an object")) {
        // show a manifest structure error pointing at the 'theme' key
    }
}

Prevention

When it happens

Trigger: Parsing a manifest where "theme" is present but its JsonElement is not a JsonObject (e.g. a quoted string, number, or array).

Common situations: "theme": "mytheme" — using a name string instead of an inline object; JSON typo like an unbalanced brace collapsing the object into a string; tools serializing the theme as a reference/id rather than an object.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManifest.java:151

            if (themeId.equals(theme.id())) {
                return theme;
            }
        }
        return null;
    }

    /// Reads the required theme declaration.
    private static List<Theme> readThemes(JsonObject object) {
        boolean hasSingleTheme = object.has("theme");
        boolean hasMultipleThemes = object.has("themes");
        if (hasSingleTheme == hasMultipleThemes) {
            throw new JsonParseException("Theme-pack manifest must declare exactly one of theme or themes");
        }

        if (hasSingleTheme) {
            JsonElement element = object.get("theme");
            if (!(element instanceof JsonObject themeObject)) {
                throw new JsonParseException("Theme-pack theme must be an object");
            }
            return List.of(Theme.fromJson(themeObject, false));
        }

        JsonElement element = object.get("themes");
        if (!(element instanceof JsonArray array)) {
            throw new JsonParseException("Theme-pack manifest is missing themes array");
        }
        if (array.isEmpty()) {
            throw new JsonParseException("Theme-pack themes array must declare at least one theme");
        }

        ArrayList<Theme> themes = new ArrayList<>(array.size());
        for (JsonElement item : array) {
            if (!(item instanceof JsonObject themeObject)) {
                throw new JsonParseException("Theme-pack theme must be an object");
            }
            themes.add(Theme.fromJson(themeObject, true));

View on GitHub (pinned to 24702dc5a0)