Anuken/Mindustry · error · RuntimeException
Nested arrays are not allowed
Error message
Nested arrays are not allowed
What it means
TypeIO.readObject throws a plain RuntimeException when it encounters type tag 6 (IntSeq) and allowArrays is false. allowArrays is passed false by the recursive readObject call inside case 22 (Object[]), so an IntSeq nested inside an Object[] is rejected to prevent unbounded nested allocation. The guard is a structural check, not a data-integrity check.
Source
Thrown at core/src/mindustry/io/TypeIO.java:201
byte type = read.b();
return switch(type){
case 0 -> null;
case 1 -> read.i();
case 2 -> read.l();
case 3 -> read.f();
case 4 -> {
byte exists = read.b();
if(exists != 0){
//in a safe context, strings can only be 1200 chars
yield read.str(safe ? 1200 : 0);
}else{
yield null;
}
}
case 5 -> mapper == null ? content.getByID(ContentType.all[read.b()], read.s()) : mapper.get(ContentType.all[read.b()], read.s());
case 6 -> {
if(!allowArrays) throw new RuntimeException("Nested arrays are not allowed");
short len = read.s();
if(len > maxArraySize) throw new RuntimeException("Invalid array size: " + len);
IntSeq arr = new IntSeq(len);
for(int i = 0; i < len; i ++) arr.add(read.i());
yield arr;
}
case 7 -> new Point2(read.i(), read.i());
case 8 -> {
if(!allowArrays) throw new RuntimeException("Nested arrays are not allowed");
int len = read.ub();
Point2[] out = new Point2[len];
for(int i = 0; i < len; i ++) out[i] = Point2.unpack(read.i());
yield out;
}
case 9 -> content.<UnlockableContent>getByID(ContentType.all[read.b()], read.s()).techNode;
case 10 -> read.bool();
case 11 -> read.d();
case 12 -> !box ? world.build(read.i()) : new BuildingBox(read.i());View on GitHub (pinned to f695ad7e60)
Solutions
- Do not nest array configs: ensure Object[] elements are scalar types (Integer, String, Content, etc.).
- If array data is legitimate, send it as a top-level config (allowArrays=true path), not inside an Object[].
- Validate on the write side that Object[] elements are non-array before calling writeObject.
Example fix
// before
Object[] nested = {new int[]{1,2,3}, "x"};
TypeIO.writeObject(write, nested); // read-back throws 'Nested arrays are not allowed'
// after
Object[] flat = {1, 2, 3, "x"}; // scalars only
TypeIO.writeObject(write, flat); Defensive patterns
Strategy: validation
Validate before calling
// Enforce no nested arrays in Object[] before writing
static void assertFlat(Object[] objs) {
for (Object o : objs) if (o != null && o.getClass().isArray())
throw new IllegalArgumentException("Nested array in Object[] config: " + o.getClass());
} Type guard
static boolean isFlatObjectArray(Object[] objs) {
if (objs == null) return true;
for (Object o : objs) if (o != null && o.getClass().isArray()) return false;
return true;
} Try / catch
try {
Object o = TypeIO.readObject(read);
} catch (RuntimeException e) {
if ("Nested arrays are not allowed".equals(e.getMessage())) {
// reject the packet/config
}
} Prevention
- Never put an array inside an Object[] config.
- Send array data as top-level configs where allowArrays is true.
- Validate flatness on the write side.
When it happens
Trigger: A serialized Object[] (tag 22) whose elements recurse via readObject(..., allowArrays=false); if any element is itself an array type (tag 6/8/14/16/18/22), this fires. Can also occur if a caller manually invokes readObject with allowArrays=false on a stream containing an array tag.
Common situations: A client sending a crafted or buggy packet that nests arrays inside an Object[] config; mod code reading configs in a restricted (safe) context.
Related errors
- Invalid array size: {}
- Player cannot configure a tile.
- Player cannot control a building.
- Player cannot control a unit.
- Player attempted to control invalid unit.
AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14).
Data as JSON: /api/errors/e5fe52634054031e.
Report an issue: GitHub.