Anuken/Mindustry · error · SerializationException
Resolving arbitrary classes (${className}) is not allowed. U
Error message
Resolving arbitrary classes (${className}) is not allowed. Use short names for classes only (without the package prefix). What it means
Thrown by the JSON parser's resolveClass override when allowClassResolution is false and libgdx attempts to resolve a fully-qualified class name from JSON. This is a deliberate security guard preventing arbitrary class instantiation from untrusted mod JSON.
Source
Thrown at core/src/mindustry/mod/ContentParser.java:417
});
}};
/** Stores things that need to be parsed fully, e.g. reading fields of content.
* This is done to accommodate binding of content names first.*/
private Seq<Runnable> reads = new Seq<>();
private Seq<Runnable> postreads = new Seq<>();
private ObjectSet<Object> toBeParsed = new ObjectSet<>();
@Nullable LoadedMod currentMod;
@Nullable Content currentContent;
@Nullable Fi currentFile;
private Json parser = new Json(){
@Override
protected <T> Class<T> resolveClass(String className){
if(allowClassResolution){
return super.resolveClass(className);
}else{
throw new SerializationException("Resolving arbitrary classes (" + className + ") is not allowed. Use short names for classes only (without the package prefix).");
}
}
@Override
protected Object newInstance(Class type){
Object o = super.newInstance(type);
onNewInstance(o, type);
return o;
}
@Override
public <T> T readValue(Class<T> type, Class elementType, JsonValue jsonData, Class keyType){
T t = internalRead(type, elementType, jsonData, keyType);
if(t != null && !Reflect.isWrapper(t.getClass()) && (type == null || !type.isPrimitive())){
checkNullFields(t);
if(jsonData.isObject()){
listeners.each(hook -> hook.parsed(type, jsonData, t));
}View on GitHub (pinned to f695ad7e60)
Solutions
- Use short class names only, without the package prefix.
- Register the intended type through the proper parser `put(...)` mapping instead of relying on resolution.
- Do not enable allowClassResolution for untrusted content.
Example fix
// before "type": "mindustry.gen.Bullet" // after "type": "Bullet" // short name only
Defensive patterns
Strategy: validation
Validate before calling
// Reject fully-qualified class names in mod JSON before resolution.
boolean isShortName(String className) {
return className != null && !className.contains(".");
} Prevention
- Use short class names only; never include package prefixes.
- Do not enable allowClassResolution for untrusted content.
- Register custom types via ContentParser.put rather than relying on resolution.
When it happens
Trigger: A mod JSON contains a fully-qualified (package-prefixed) class name in a context where libgdx tries to resolve a class, while allowClassResolution is disabled (the default for mod content).
Common situations: Author writes full package paths (e.g. mindustry.gen.Bullet), ports content expecting automatic class resolution, or supplies JSON crafted to instantiate arbitrary classes.
Related errors
- Expecting an object, but found: '${jsonMap}'
- Attribute definitions must be objects, e.g. {heat: 10}
- Unknown status effect: '
- Unknown unit command name:
- Unit commands must be strings.
AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14).
Data as JSON: /api/errors/5040ea47980f7683.
Report an issue: GitHub.