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
- Make "theme" a JSON object with the theme fields: { "theme": { "id": "main", ... } }.
- If you meant to reference an external theme by id, instead inline the full theme definition — string references are not supported.
- 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
- Always declare 'theme' as an inline JSON object with the theme fields.
- Validate manifest JSON structure with a schema or linter before loading.
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
- Theme-pack manifest field must be a string
- Theme-pack author must be an object or a string
- Missing author name:
- Manifest is null
- Invalid theme-pack manifest
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)