{"record":{"id":"dd3c59ff4c19258f","repo":"Grasscutters/Grasscutter","slug":"invalid-intlist-definition","errorCode":null,"errorMessage":"Invalid IntList definition - ","messagePattern":"Invalid IntList definition - ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/main/java/emu/grasscutter/utils/JsonAdapters.java","lineNumber":66,"sourceCode":"        }\n\n        @Override\n        public void write(JsonWriter writer, DynamicFloat f) {}\n    }\n\n    class IntListAdapter extends TypeAdapter<IntList> {\n        @Override\n        public IntList read(JsonReader reader) throws IOException {\n            if (Objects.requireNonNull(reader.peek()) == JsonToken.BEGIN_ARRAY) {\n                reader.beginArray();\n                val i = new IntArrayList();\n                while (reader.hasNext()) i.add(reader.nextInt());\n                reader.endArray();\n                i.trim(); // We might have a ton of these from resources and almost all of them\n                // immutable, don't overprovision!\n                return i;\n            }\n            throw new IOException(\"Invalid IntList definition - \" + reader.peek().name());\n        }\n\n        @Override\n        public void write(JsonWriter writer, IntList l) throws IOException {\n            writer.beginArray();\n            for (val i : l) // .forEach() doesn't appreciate exceptions\n            writer.value(i);\n            writer.endArray();\n        }\n    }\n\n    public class ByteArrayAdapter extends TypeAdapter<byte[]> {\n        @Override\n        public void write(JsonWriter out, byte[] value) throws IOException {\n            out.value(Utils.base64Encode(value));\n        }\n\n        @Override","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/Grasscutters/Grasscutter/blob/f373827a83d3e688fd3c6afb1e1c3759ca1d61c9/src/main/java/emu/grasscutter/utils/JsonAdapters.java#L48-L84","documentation":"The IntList adapter only accepts a JSON array of integers; if the token at the current position is not BEGIN_ARRAY (e.g. an object, string, or null), it throws this IOException after including the peeked token name. It exists to fail fast on schema-mismatched resource data instead of silently misreading an IntList field.","triggerScenarios":"An IntList-typed field in a resource JSON contains a single integer, a string, an object, or null instead of an array of numbers, e.g. \"param_list\": 5 or \"param_list\": {\"a\":1}, during Gson resource loading.","commonSituations":"Resources dumped from a different game version where a field changed from list to scalar, hand-edited configs, or JSON generators that omit empty arrays (writing null instead).","solutions":["Fix the field in the flagged resource file to be an array of integers, e.g. [1,2,3]","If the value is null or scalar, wrap or replace it: 5 -> [5], null -> []","Re-dump resources matching your Grasscutter/server version","Grep your resource folder for the field name to fix all affected files at once"],"exampleFix":"// before (resource JSON)\n\"param_list\": 5\n// after\n\"param_list\": [5]","handlingStrategy":"validation","validationCode":"// Verify IntList fields are arrays of integers before Gson parsing\nstatic boolean isValidIntList(com.google.gson.JsonElement e) {\n    if (e == null || !e.isJsonArray()) return false;\n    for (var el : e.getAsJsonArray()) {\n        if (!el.isJsonPrimitive() || !el.getAsJsonPrimitive().isNumber()) return false;\n    }\n    return true;\n}","typeGuard":"static boolean isIntArray(com.google.gson.JsonElement el) {\n    return el != null && el.isJsonArray()\n        && java.util.stream.StreamSupport.stream(el.getAsJsonArray().spliterator(), false)\n            .allMatch(x -> x.isJsonPrimitive() && x.getAsJsonPrimitive().isNumber());\n}","tryCatchPattern":"try {\n    IntList list = gson.fromJson(json, IntList.class);\n} catch (IOException | JsonParseException e) {\n    logger.error(\"Invalid IntList definition: {}\", e.getMessage());\n    IntList list = new IntList(); // empty fallback\n}","preventionTips":["Always encode IntList fields as JSON arrays, even when there is a single value ([5], not 5)","Replace null with [] in generated dumps","Keep resource dumps in sync with the server version","Grep resources for scalar-valued list fields during a version migration"],"tags":["gson","json","deserialization","grasscutter"],"backgroundTag":"json-deserialization-failed","analyzedSha":"f373827a83d3e688fd3c6afb1e1c3759ca1d61c9","analyzedAt":"2026-09-03T22:43:49.407Z","contentChangedAt":"2026-09-03T22:43:49.407Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}