Grasscutters/Grasscutter · error · IOException
Invalid DynamicFloat definition -
Error message
Invalid DynamicFloat definition -
What it means
Grasscutter's DynamicFloat Gson adapter expects a JSON array whose elements are only strings, numbers, or booleans (stack ops). When the next JSON token is anything else (e.g. OBJECT, NULL, or a non-array value), the adapter throws this IOException with the offending token name appended. Here the token name is empty in the message, indicating the peek value was unexpected during parsing of a resource file.
Source
Thrown at src/main/java/emu/grasscutter/utils/JsonAdapters.java:38
case STRING -> {
return new DynamicFloat(reader.nextString());
}
case NUMBER -> {
return new DynamicFloat((float) reader.nextDouble());
}
case BOOLEAN -> {
return new DynamicFloat(reader.nextBoolean());
}
case BEGIN_ARRAY -> {
reader.beginArray();
val opStack = new ArrayList<DynamicFloat.StackOp>();
while (reader.hasNext()) {
opStack.add(
switch (reader.peek()) {
case STRING -> new DynamicFloat.StackOp(reader.nextString());
case NUMBER -> new DynamicFloat.StackOp((float) reader.nextDouble());
case BOOLEAN -> new DynamicFloat.StackOp(reader.nextBoolean());
default -> throw new IOException(
"Invalid DynamicFloat definition - " + reader.peek().name());
});
}
reader.endArray();
return new DynamicFloat(opStack);
}
default -> throw new IOException(
"Invalid DynamicFloat definition - " + reader.peek().name());
}
}
@Override
public void write(JsonWriter writer, DynamicFloat f) {}
}
class IntListAdapter extends TypeAdapter<IntList> {
@Override
public IntList read(JsonReader reader) throws IOException {View on GitHub (pinned to f373827a83)
Solutions
- Open the resource JSON named in the stack trace and fix the DynamicFloat field to be an array of strings/numbers/booleans
- Replace null or nested objects in the field with a valid array, e.g. ["%HP"] or [100.0]
- Re-download or re-dump the resources from a source matching your Grasscutter version
- Check the JsonAdapters DynamicFloat adapter version matches the resource data format
Example fix
// before (resource JSON)
"battle_progress": {"value": 100}
// after
"battle_progress": [100.0] Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate a DynamicFloat resource value before handing it to Gson
static boolean isValidDynamicFloat(com.google.gson.JsonElement e) {
if (e == null || e.isJsonNull()) return false;
if (e.isJsonPrimitive()) {
var p = e.getAsJsonPrimitive();
return p.isString() || p.isNumber() || p.isBoolean();
}
if (e.isJsonArray()) {
for (var el : e.getAsJsonArray()) {
if (!el.isJsonPrimitive()) return false;
var p = el.getAsJsonPrimitive();
if (!(p.isString() || p.isNumber() || p.isBoolean())) return false;
}
return true;
}
return false; // objects and other tokens are rejected by the adapter
} Type guard
static boolean isDynamicFloatPrimitive(com.google.gson.JsonElement el) {
return el != null && el.isJsonPrimitive()
&& (el.getAsJsonPrimitive().isString()
|| el.getAsJsonPrimitive().isNumber()
|| el.getAsJsonPrimitive().isBoolean());
} Try / catch
try {
DynamicFloat f = gson.fromJson(json, DynamicFloat.class);
} catch (IOException | JsonParseException e) {
logger.error("Malformed DynamicFloat in resource JSON: {}", e.getMessage());
DynamicFloat f = new DynamicFloat(0f); // safe default
} Prevention
- Only use resource dumps that match your Grasscutter version
- Never hand-edit DynamicFloat fields without keeping the array-of-scalars shape
- Lint resource JSONs at load time with the validation function before Gson deserialization
- Validate resource files after download (checksum/schema check)
When it happens
Trigger: Parsing a resource/quest JSON file whose DynamicFloat field contains a nested JSON object, null, or a non-array scalar (e.g. a bare number or string where an array of stack ops was expected) while loading game resources via Gson with this TypeAdapter registered.
Common situations: Game data files from a mismatched resources version (dumped data newer/older than the parser expects), hand-edited JSON that replaced the array with an object or null, or a corrupted/truncated download where the array content is malformed.
Related errors
- Invalid IntList definition -
- Invalid GridPosition definition -
- Invalid field in Position definition -
- Invalid Position definition -
- Invalid Enum definition -
AI-assisted analysis of Grasscutters/Grasscutter@f373827a83 (2026-09-03).
Data as JSON: /api/errors/72da99c95a6f1713.
Report an issue: GitHub.