{"record":{"id":"c40a874b963e4374","repo":"HMCL-dev/HMCL","slug":"unexpected-json-element","errorCode":null,"errorMessage":"Unexpected json element: ","messagePattern":"Unexpected json element: ","errorType":"exception","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedText.java","lineNumber":78,"sourceCode":"                throw new JsonParseException(\"Localized text cannot be empty object\");\n            }\n\n            var map = new LinkedHashMap<String, String>();\n            jsonObject.asMap().forEach((k, v) -> {\n                if (v instanceof JsonPrimitive primitive) {\n                    map.put(k, primitive.getAsString());\n                } else {\n                    throw new JsonParseException(\"Localized text entry cannot be \" + v.getClass());\n                }\n            });\n            return new LocalizedText(map);\n        }\n\n        if (element instanceof JsonPrimitive primitive) {\n            return new LocalizedText(primitive.getAsString());\n        }\n\n        throw new JsonParseException(\"Unexpected json element: \" + element);\n    }\n\n    /// Reads a localized text value from a streaming JSON reader.\n    ///\n    /// The reader accepts JSON `null`, a JSON string, or an object whose values are strings.\n    ///\n    /// @param jsonReader the reader positioned at the next localized text value\n    /// @return the parsed localized text, or `null` if the next token is JSON `null`\n    /// @throws IOException         if reading from `jsonReader` fails\n    /// @throws JsonSyntaxException if the next token is neither JSON `null`, a string, nor an object\n    public static @Nullable LocalizedText read(JsonReader jsonReader) throws IOException {\n        JsonToken nextToken = jsonReader.peek();\n        if (nextToken == JsonToken.NULL) {\n            jsonReader.nextNull();\n            return null;\n        } else if (nextToken == JsonToken.STRING) {\n            return new LocalizedText(jsonReader.nextString());\n        } else if (nextToken == JsonToken.BEGIN_OBJECT) {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedText.java#L60-L96","documentation":"LocalizedText.fromJson accepts JSON null, a string primitive, or an object of string values. Any other JsonElement kind (array, or unexpected element types) falls through all accepted branches and is rejected with this JsonParseException.","triggerScenarios":"Calling LocalizedText.fromJson with a JsonArray (or any non-null, non-primitive, non-object element), e.g. a field containing [\"a\",\"b\"].","commonSituations":"Upstream format change where localized fields became arrays; merging code that produces arrays; malformed hand-edited JSON.","solutions":["Replace the array with either a single string or an object mapping locale keys to strings.","Check the element kind (isJsonPrimitive/isJsonObject/isJsonNull) before calling fromJson.","Trace the producer of the JSON and fix it to emit the documented shapes only."],"exampleFix":"// before\n{\"title\": [\"Hello\", \"Bonjour\"]}\n\n// after\n{\"title\": {\"en\": \"Hello\", \"fr\": \"Bonjour\"}}","handlingStrategy":"type-guard","validationCode":"if (el != null && !el.isJsonNull() && !el.isJsonPrimitive() && !el.isJsonObject()) throw new IllegalArgumentException(\"Unsupported element for LocalizedText\");","typeGuard":"static boolean isLocalizedTextShape(@Nullable JsonElement el) { return el == null || el.isJsonNull() || el.isJsonPrimitive() || el.isJsonObject(); }","tryCatchPattern":"try { return LocalizedText.fromJson(el); } catch (JsonParseException e) { log.warn(\"Unexpected localized element\", e); return null; }","preventionTips":["Only produce null/string/object-of-strings for localized fields.","Check element kind before parsing third-party JSON.","Document the accepted shapes to producers of the data."],"tags":["json","i18n","unexpected-value","validation"],"backgroundTag":"unexpected-response-shape","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"}