{"record":{"id":"72997ab5e4451dca","repo":"HMCL-dev/HMCL","slug":"unexpected-token","errorCode":null,"errorMessage":"Unexpected token ","messagePattern":"Unexpected token ","errorType":"exception","errorClass":"JsonSyntaxException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedText.java","lineNumber":110,"sourceCode":"            jsonReader.nextNull();\n            return null;\n        } else if (nextToken == JsonToken.STRING) {\n            return new LocalizedText(jsonReader.nextString());\n        } else if (nextToken == JsonToken.BEGIN_OBJECT) {\n            LinkedHashMap<String, String> localizedValues = new LinkedHashMap<>();\n\n            jsonReader.beginObject();\n            while (jsonReader.hasNext()) {\n                String name = jsonReader.nextName();\n                String value = jsonReader.nextString();\n\n                localizedValues.put(name, value);\n            }\n            jsonReader.endObject();\n\n            return new LocalizedText(localizedValues);\n        } else {\n            throw new JsonSyntaxException(\"Unexpected token \" + nextToken);\n        }\n    }\n\n    /// Creates a locale-independent text value.\n    ///\n    /// @param value the text value\n    /// @return a localized text object that serializes to a JSON string.\n    public static LocalizedText plain(String value) {\n        return new LocalizedText(value);\n    }\n\n    /// Locale-independent text used when this instance is not backed by localized values.\n    private final @Nullable String value;\n\n    /// Text values keyed by language keys generated by [LocaleUtils#toLanguageKey(Locale)].\n    private final @Nullable @Unmodifiable Map<String, String> localizedValues;\n\n    /// Creates a locale-independent text value.","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedText.java#L92-L128","documentation":"The streaming variant LocalizedText.read (JsonReader-based) accepts null, a string, or an object of string values. If the next token is any other JSON token (BEGIN_ARRAY, NUMBER, BOOLEAN, etc.), it throws a JsonSyntaxException reporting the token.","triggerScenarios":"A JsonReader positioned at a token other than NULL, STRING, or BEGIN_OBJECT when LocalizedText.read is invoked — most commonly an array at a localized-text field.","commonSituations":"JSON documents whose localized fields hold arrays or numbers; deserializing with the wrong adapter/type after a schema change; corrupted files.","solutions":["Fix the JSON so the field is a string, an object of strings, or null.","Peek the token (reader.peek()) and skip/handle non-supported shapes before calling read.","Update the producer or adapter so the streaming path matches the actual data shape."],"exampleFix":"// before\n{\"name\": [\"Hello\"]} // BEGIN_ARRAY hits read()\n\n// after\n{\"name\": \"Hello\"} // or {\"en\": \"Hello\"}, or null","handlingStrategy":"type-guard","validationCode":"if (reader.peek() != JsonToken.NULL && reader.peek() != JsonToken.STRING && reader.peek() != JsonToken.BEGIN_OBJECT) throw new IllegalStateException(\"Unsupported token for LocalizedText\");","typeGuard":"static boolean isLocalizedToken(JsonReader r) throws IOException { JsonToken t = r.peek(); return t == JsonToken.NULL || t == JsonToken.STRING || t == JsonToken.BEGIN_OBJECT; }","tryCatchPattern":"try { return LocalizedText.read(reader); } catch (JsonSyntaxException e) { log.warn(\"Unexpected token for localized text\", e); reader.skipValue(); return null; }","preventionTips":["Peek the token before reading typed values from streams.","Keep streaming and tree-based parsers fed the same schema.","Fix producers that emit arrays for localized fields."],"tags":["json","i18n","syntax","streaming"],"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-23T08:17:48.524Z"}