HMCL-dev/HMCL · error · JsonParseException
Theme-pack manifest is missing
Error message
Theme-pack manifest is missing ${fieldName} What it means
Thrown by requireMemberString when a required string member of the theme-pack manifest is absent. The adapter calls this for mandatory fields like "id" and "version"; a missing key means the manifest is incomplete and the pack cannot be identified.
Solutions
- Add the named field to the manifest, e.g. "id": "com.example.mypack", "version": "1.0.0".
- Check spelling and casing of the key — the lookup is exact.
- Compare against the ThemePackManifest.CURRENT_SCHEMA (theme-pack 1.0.0) field list.
Example fix
// before
{
"schemaVersion": "theme-pack:1.0.0",
"name": "My Pack"
}
// after
{
"schemaVersion": "theme-pack:1.0.0",
"id": "com.example.mypack",
"version": "1.0.0",
"name": "My Pack"
} Defensive patterns
Strategy: validation
Validate before calling
for (String required : new String[]{"id", "version"}) {
if (!manifestJson.has(required)) {
throw new IllegalArgumentException("manifest missing required field: " + required);
}
} Type guard
static boolean hasRequiredStringFields(JsonObject manifest, String... fields) {
for (String f : fields) {
if (!(manifest.get(f) instanceof JsonPrimitive p) || !p.isString()) return false;
}
return true;
} Try / catch
try {
ThemePackManifest pack = gson.fromJson(json, ThemePackManifest.class);
} catch (JsonParseException e) {
// show which field is missing so the pack author can fix it
} Prevention
- Start new manifests from the official template with id/version pre-filled
- Keep field names lowercase and exact ("id", "version", "name")
- Validate against ThemePackManifest.CURRENT_SCHEMA before packaging
When it happens
Trigger: Deserializing a manifest JSON that omits "id" or "version" (or any other field routed through requireMemberString). Message is parameterized with the missing field name.
Common situations: Author created a minimal manifest and skipped required metadata; a field was renamed (e.g. "packageId" instead of "id"); an editor stripped keys it considered empty.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Missing author name:
- Theme-pack author must be an object or a string
- Manifest is null
- Invalid theme-pack manifest
- Theme pack value is missing
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/f77f78188b9612af.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManifest.java:194
if (themes.size() <= 1) {
return;
}
for (Theme theme : themes) {
if (theme.id() == null) {
throw new IllegalArgumentException("Theme ID is required when a theme pack declares multiple themes");
}
if (theme.name() == null) {
throw new IllegalArgumentException("Theme name is required when a theme pack declares multiple themes");
}
}
}
/// Reads a required string member.
private static String requireMemberString(JsonObject object, String fieldName) {
JsonElement element = object.get(fieldName);
if (element == null) {
throw new JsonParseException("Theme-pack manifest is missing " + fieldName);
}
if (!(element instanceof JsonPrimitive primitive) || !primitive.isString()) {
throw new JsonParseException("Theme-pack manifest field must be a string: " + fieldName);
}
return requireNonBlank(primitive.getAsString(), fieldName);
}
/// Parses a localized text value.
static LocalizedText parseLocalizedText(JsonElement element, String field) {
if (element instanceof JsonPrimitive primitive && primitive.isString()) {
return LocalizedText.plain(requireNonBlank(primitive.getAsString(), field));
}
if (element instanceof JsonObject localizedObject) {
if (localizedObject.isEmpty()) {
throw new JsonParseException("Localized text field is empty: " + field);
}
LinkedHashMap<String, String> localizedValues = new LinkedHashMap<>();View on GitHub (pinned to 24702dc5a0)