{"record":{"id":"ec2b73538aa14620","repo":"Grasscutters/Grasscutter","slug":"invalid-gridposition-definition","errorCode":null,"errorMessage":"Invalid GridPosition definition - ","messagePattern":"Invalid GridPosition definition - ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/main/java/emu/grasscutter/utils/JsonAdapters.java","lineNumber":99,"sourceCode":"            out.value(Utils.base64Encode(value));\n        }\n\n        @Override\n        public byte[] read(JsonReader in) throws IOException {\n            return Utils.base64Decode(in.nextString());\n        }\n    }\n\n    class GridPositionAdapter extends TypeAdapter<GridPosition> {\n        @Override\n        public void write(JsonWriter out, GridPosition value) throws IOException {\n            out.value(\"(\" + value.getX() + \", \" + value.getZ() + \", \" + value.getWidth() + \")\");\n        }\n\n        @Override\n        public GridPosition read(JsonReader in) throws IOException {\n            if (in.peek() != JsonToken.STRING)\n                throw new IOException(\"Invalid GridPosition definition - \" + in.peek().name());\n\n            // GridPosition follows the format of: (x, y, z).\n            // Flatten to (x,y,z) for easier parsing.\n            var str = in.nextString().replace(\"(\", \"\").replace(\")\", \"\").replace(\" \", \"\");\n            var split = str.split(\",\");\n\n            if (split.length != 3)\n                throw new IOException(\"Invalid GridPosition definition - \" + in.peek().name());\n\n            return new GridPosition(\n                    Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));\n        }\n    }\n\n    class PositionAdapter extends TypeAdapter<Position> {\n        @Override\n        public Position read(JsonReader reader) throws IOException {\n            switch (reader.peek()) {","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/Grasscutters/Grasscutter/blob/f373827a83d3e688fd3c6afb1e1c3759ca1d61c9/src/main/java/emu/grasscutter/utils/JsonAdapters.java#L81-L117","documentation":"The GridPosition adapter expects its JSON value to be a string of the form \"(x, y, z)\". If the peeked token is not a STRING (e.g. an array, object, number, or null), it throws this IOException naming the unexpected token. This guards the string-parsing logic that strips parentheses and splits on commas.","triggerScenarios":"A GridPosition field in a resource/config JSON is encoded as an array [x,y,z], a JSON object, a number, or null instead of the string \"(x, y, z)\" when deserialized by Gson.","commonSituations":"Resource dumps from a different game version where GridPosition fields changed representation, custom tooling that serializes positions as arrays, or hand-edited spawn/blocking-point data files.","solutions":["Change the field value in the flagged JSON file to the string form, e.g. \"(1, 2, 3)\"","If the source data provides [x,y,z], convert it to the parenthesized string before loading","Re-acquire resources matching the version Grasscutter's adapter was written for","Locate which file/field failed by reading the Gson path in the stack trace"],"exampleFix":"// before (resource JSON)\n\"size\": [1, 2, 3]\n// after\n\"size\": \"(1, 2, 3)\"","handlingStrategy":"validation","validationCode":"// Check GridPosition fields are the expected \"(x, y, z)\" string before parsing\nstatic boolean isValidGridPosition(com.google.gson.JsonElement e) {\n    return e != null && e.isJsonPrimitive() && e.getAsJsonPrimitive().isString()\n        && e.getAsString().matches(\"\\\\s*\\\\(\\\\s*-?\\\\d+\\\\s*,\\\\s*-?\\\\d+\\\\s*,\\\\s*-?\\\\d+\\\\s*\\\\)\\\\s*\");\n}","typeGuard":"static boolean isGridPositionString(com.google.gson.JsonElement el) {\n    if (el == null || !el.isJsonPrimitive() || !el.getAsJsonPrimitive().isString()) return false;\n    return el.getAsString().trim().matches(\"\\\\(-?\\\\d+,\\\\s*-?\\\\d+,\\\\s*-?\\\\d+\\\\)\");\n}","tryCatchPattern":"try {\n    GridPosition p = gson.fromJson(json, GridPosition.class);\n} catch (IOException | JsonParseException e) {\n    logger.error(\"Invalid GridPosition definition: {}\", e.getMessage());\n    GridPosition p = new GridPosition(0, 0, 0); // neutral fallback\n}","preventionTips":["Serialize GridPosition as the string \"(x, y, z)\", never as arrays or objects","Do not convert coordinates to JSON arrays when re-dumping resources","Validate position strings with a regex before loading","Use one canonical resource source to avoid mixed-format files"],"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"}