Grasscutters/Grasscutter · error · IOException

Invalid Enum definition -

Error message

Invalid Enum definition - 

What it means

The enum TypeAdapter factory maps enum constants by name string and by integer ordinal-as-string; any other JSON token (object, array, boolean, null) cannot represent an enum and throws this IOException. Note the returned map.get(...) may itself yield null for unknown names/numbers, but non-scalar tokens hit this throw directly.

Source

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

                        for (var constant : enumConstants) {
                            var accessible = f.canAccess(constant);
                            f.setAccessible(true);
                            map.put(String.valueOf(f.getInt(constant)), constant);
                            f.setAccessible(accessible);
                        }
                    } catch (IllegalAccessException e) {
                        // System.out.println("Failed to access enum id field.");
                    }
                    break;
                }
            }

            return new TypeAdapter<>() {
                public T read(JsonReader reader) throws IOException {
                    return switch (reader.peek()) {
                        case STRING -> map.get(reader.nextString());
                        case NUMBER -> map.get(String.valueOf(reader.nextInt()));
                        default -> throw new IOException("Invalid Enum definition - " + reader.peek().name());
                    };
                }

                public void write(JsonWriter writer, T value) throws IOException {
                    writer.value(value.toString());
                }
            };
        }
    }
}

View on GitHub (pinned to f373827a83)

Solutions

  1. Change the JSON value to the enum's name string (e.g. "OPEN") or its integer form
  2. Replace JSON null with a valid enum name, or declare the field nullable/skip it
  3. Preprocess input JSON to unwrap nested enum objects before Gson parsing
  4. Check which enum and file failed (message appends reader.peek().name()) and fix that value

Example fix

// before
"openState": {"id": 1}
// after
"openState": 1
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidEnumValue(Class<? extends Enum<?>> type, com.google.gson.JsonElement el) {
  if (el == null || !el.isJsonPrimitive()) return false;
  String s = el.getAsString();
  for (Enum<?> c : type.getEnumConstants())
    if (c.name().equals(s) || String.valueOf(c.ordinal()).equals(s)) return true;
  return false;
}

Type guard

boolean isEnumToken(com.google.gson.JsonElement el) {
  return el != null && el.isJsonPrimitive()
      && (el.getAsJsonPrimitive().isString() || el.getAsJsonPrimitive().isNumber());
}

Try / catch

try {
  MyEnum v = gson.fromJson(el, MyEnum.class);
} catch (IOException e) {
  logger.warn("Bad enum token: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Deserializing an enum-typed field where the JSON value is an object, array, boolean, or null token; e.g. "openState": {"value":1} or "openState": [1] instead of "openState": 1 or "openState": "OPEN".

Common situations: Configs exported with wrapped enum objects by other frameworks; null enum values in JSON where the field is non-nullable in Java; hand-edited resources using wrong value types.

Related errors


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