Grasscutters/Grasscutter · error · IOException

Invalid IntList definition -

Error message

Invalid IntList definition - 

What it means

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.

Source

Thrown at src/main/java/emu/grasscutter/utils/JsonAdapters.java:66

        }

        @Override
        public void write(JsonWriter writer, DynamicFloat f) {}
    }

    class IntListAdapter extends TypeAdapter<IntList> {
        @Override
        public IntList read(JsonReader reader) throws IOException {
            if (Objects.requireNonNull(reader.peek()) == JsonToken.BEGIN_ARRAY) {
                reader.beginArray();
                val i = new IntArrayList();
                while (reader.hasNext()) i.add(reader.nextInt());
                reader.endArray();
                i.trim(); // We might have a ton of these from resources and almost all of them
                // immutable, don't overprovision!
                return i;
            }
            throw new IOException("Invalid IntList definition - " + reader.peek().name());
        }

        @Override
        public void write(JsonWriter writer, IntList l) throws IOException {
            writer.beginArray();
            for (val i : l) // .forEach() doesn't appreciate exceptions
            writer.value(i);
            writer.endArray();
        }
    }

    public class ByteArrayAdapter extends TypeAdapter<byte[]> {
        @Override
        public void write(JsonWriter out, byte[] value) throws IOException {
            out.value(Utils.base64Encode(value));
        }

        @Override

View on GitHub (pinned to f373827a83)

Solutions

  1. Fix the field in the flagged resource file to be an array of integers, e.g. [1,2,3]
  2. If the value is null or scalar, wrap or replace it: 5 -> [5], null -> []
  3. Re-dump resources matching your Grasscutter/server version
  4. Grep your resource folder for the field name to fix all affected files at once

Example fix

// before (resource JSON)
"param_list": 5
// after
"param_list": [5]
Defensive patterns

Strategy: validation

Validate before calling

// Verify IntList fields are arrays of integers before Gson parsing
static boolean isValidIntList(com.google.gson.JsonElement e) {
    if (e == null || !e.isJsonArray()) return false;
    for (var el : e.getAsJsonArray()) {
        if (!el.isJsonPrimitive() || !el.getAsJsonPrimitive().isNumber()) return false;
    }
    return true;
}

Type guard

static boolean isIntArray(com.google.gson.JsonElement el) {
    return el != null && el.isJsonArray()
        && java.util.stream.StreamSupport.stream(el.getAsJsonArray().spliterator(), false)
            .allMatch(x -> x.isJsonPrimitive() && x.getAsJsonPrimitive().isNumber());
}

Try / catch

try {
    IntList list = gson.fromJson(json, IntList.class);
} catch (IOException | JsonParseException e) {
    logger.error("Invalid IntList definition: {}", e.getMessage());
    IntList list = new IntList(); // empty fallback
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of Grasscutters/Grasscutter@f373827a83 (2026-09-03). Data as JSON: /api/errors/dd3c59ff4c19258f. Report an issue: GitHub.