{"record":{"id":"f77f78188b9612af","repo":"HMCL-dev/HMCL","slug":"theme-pack-manifest-is-missing-fieldname","errorCode":null,"errorMessage":"Theme-pack manifest is missing ${fieldName}","messagePattern":"Theme-pack manifest is missing (.+?)","errorType":"validation","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManifest.java","lineNumber":194,"sourceCode":"        if (themes.size() <= 1) {\n            return;\n        }\n\n        for (Theme theme : themes) {\n            if (theme.id() == null) {\n                throw new IllegalArgumentException(\"Theme ID is required when a theme pack declares multiple themes\");\n            }\n            if (theme.name() == null) {\n                throw new IllegalArgumentException(\"Theme name is required when a theme pack declares multiple themes\");\n            }\n        }\n    }\n\n    /// Reads a required string member.\n    private static String requireMemberString(JsonObject object, String fieldName) {\n        JsonElement element = object.get(fieldName);\n        if (element == null) {\n            throw new JsonParseException(\"Theme-pack manifest is missing \" + fieldName);\n        }\n        if (!(element instanceof JsonPrimitive primitive) || !primitive.isString()) {\n            throw new JsonParseException(\"Theme-pack manifest field must be a string: \" + fieldName);\n        }\n        return requireNonBlank(primitive.getAsString(), fieldName);\n    }\n\n    /// Parses a localized text value.\n    static LocalizedText parseLocalizedText(JsonElement element, String field) {\n        if (element instanceof JsonPrimitive primitive && primitive.isString()) {\n            return LocalizedText.plain(requireNonBlank(primitive.getAsString(), field));\n        }\n        if (element instanceof JsonObject localizedObject) {\n            if (localizedObject.isEmpty()) {\n                throw new JsonParseException(\"Localized text field is empty: \" + field);\n            }\n\n            LinkedHashMap<String, String> localizedValues = new LinkedHashMap<>();","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManifest.java#L176-L212","documentation":"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.","triggerScenarios":"Deserializing a manifest JSON that omits \"id\" or \"version\" (or any other field routed through requireMemberString). Message is parameterized with the missing field name.","commonSituations":"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.","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."],"exampleFix":"// before\n{\n  \"schemaVersion\": \"theme-pack:1.0.0\",\n  \"name\": \"My Pack\"\n}\n// after\n{\n  \"schemaVersion\": \"theme-pack:1.0.0\",\n  \"id\": \"com.example.mypack\",\n  \"version\": \"1.0.0\",\n  \"name\": \"My Pack\"\n}","handlingStrategy":"validation","validationCode":"for (String required : new String[]{\"id\", \"version\"}) {\n    if (!manifestJson.has(required)) {\n        throw new IllegalArgumentException(\"manifest missing required field: \" + required);\n    }\n}","typeGuard":"static boolean hasRequiredStringFields(JsonObject manifest, String... fields) {\n    for (String f : fields) {\n        if (!(manifest.get(f) instanceof JsonPrimitive p) || !p.isString()) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    ThemePackManifest pack = gson.fromJson(json, ThemePackManifest.class);\n} catch (JsonParseException e) {\n    // show which field is missing so the pack author can fix it\n}","preventionTips":["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"],"tags":["json","manifest","missing-field","theme-pack"],"backgroundTag":"missing-required-config-field","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}