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

  1. Add the named field to the manifest, e.g. "id": "com.example.mypack", "version": "1.0.0".
  2. Check spelling and casing of the key — the lookup is exact.
  3. 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

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


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)