HMCL-dev/HMCL · error · JsonParseException
Theme-pack themes array must declare at least one theme
Error message
Theme-pack themes array must declare at least one theme
What it means
Thrown by ThemePackManifest.readThemes when the "themes" array is present and is an array but contains zero elements. A theme pack must ship at least one selectable theme; an empty array would make the pack unusable, so it is rejected during deserialization.
Solutions
- Add at least one theme object to the "themes" array.
- If only one theme is intended, either keep it in the array or switch to the singular "theme": { ... } form.
- Ship a placeholder theme if the pack must be structurally valid before real themes are authored.
Example fix
// before
"themes": []
// after
"themes": [
{ "id": "default", "name": "Default" }
] Defensive patterns
Strategy: validation
Validate before calling
JsonArray themes = manifestJson.has("themes") && manifestJson.get("themes") instanceof JsonArray a ? a : null;
if (themes != null && themes.isEmpty()) {
throw new IllegalArgumentException("'themes' must contain at least one theme");
} Type guard
static boolean hasNonEmptyThemesArray(JsonObject manifest) {
return manifest.get("themes") instanceof JsonArray a && !a.isEmpty();
} Try / catch
try {
ThemePackManifest pack = gson.fromJson(json, ThemePackManifest.class);
} catch (JsonParseException e) {
// mark the pack invalid; surface 'no themes declared' to the user
} Prevention
- Never distribute a pack template with an empty themes array
- Add a packaging test that loads every shipped manifest
- If a pack is theme-less during development, keep one placeholder theme
When it happens
Trigger: Deserializing a manifest with "themes": []. Any load of a theme pack whose manifest declares the multi-theme form but lists no themes.
Common situations: Author removed all theme entries while refactoring the manifest; a build script stripped the array contents; a pack template was distributed without its example theme filled in.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Theme-pack author must be an object or a string
- Missing author name:
- Manifest is null
- Invalid theme-pack manifest
- Theme-pack manifest must declare exactly one of theme or…
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/4e5e2b6b3cd07ab4.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManifest.java:161
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));
}
return themes;
}
/// Checks that theme IDs and names are present whenever the manifest needs them for disambiguation.
private static void checkThemeIdentities(List<Theme> themes) {
if (themes.size() <= 1) {
return;
}
View on GitHub (pinned to 24702dc5a0)