Anuken/Mindustry · error · SerializationException
Patch must be a JSON object.
Error message
Patch must be a JSON object.
What it means
DataPatcher parses each patch asset's JSON; if the parsed root value is not a JsonValue object (e.g. the patch is an array, scalar, or parsed to a non-JsonValue type), it throws SerializationException 'Patch must be a JSON object.' Patches are applied as object key/value merges.
Source
Thrown at core/src/mindustry/mod/DataPatcher.java:231
if(cont.minfo.asset != null) cont.minfo.asset.errored = true;
parser.markError(cont, dpMod, cont.minfo.sourceFile, t);
}
}
}
if(reloadContentWorld) fixContentArrays();
}
var patchIt = patches.iterator();
while(patchIt.hasNext()){
PatchAsset set = patchIt.next();
set.warnings.clear();
set.error = false;
try{
Object someValue = parser.getJson().fromJson(null, Jval.read(set.patch).toString(Jformat.plain));
if(!(someValue instanceof JsonValue value)) throw new SerializationException("Patch must be a JSON object.");
if(Vars.state.rules.planet != null && value.has("requiredPlanets")){
JsonValue req = value.get("requiredPlanets");
value.remove("requiredPlanets");
//this should be ignored unless this instance is a dedicated server
if(Vars.headless){
String[] planets = req.isArray() ? req.asStringArray() : new String[]{req.asString()};
if(!Structs.contains(planets, Vars.state.rules.planet.name)){
patchIt.remove();
continue;
}
}
}
set.json = value;
currentlyApplyingPatch = set;
visitStack.clear();View on GitHub (pinned to f695ad7e60)
Solutions
- Make the patch file a JSON object at the top level.
- Validate it parses to an object before submission.
- Remove array-style patch-op wrappers if present.
Example fix
// before (patch.json)
[ { "op": "replace", "path": "a", "value": 1 } ]
// after
{ "a": 1 } Defensive patterns
Strategy: validation
Validate before calling
// Ensure a patch is a JSON object before applying.
Object parsed = parser.getJson().fromJson(null, Jval.read(patch).toString(Jformat.plain));
if(!(parsed instanceof JsonValue v) || !v.isObject()) {
throw new SerializationException("Patch must be a JSON object.");
} Type guard
boolean isJsonObjectPatch(String json){
try {
Object p = parser.getJson().fromJson(null, Jval.read(json).toString(Jformat.plain));
return p instanceof JsonValue v && v.isObject();
} catch(Exception e){ return false; }
} Try / catch
try {
DataPatcher.apply(patch);
} catch(SerializationException e) {
if(e.getMessage().equals("Patch must be a JSON object.")) { /* rewrite patch root as object */ }
else throw e;
} Prevention
- Author patches as top-level JSON objects.
- Validate patch JSON shape in a pre-submit lint step.
- Do not wrap patch contents in arrays of RFC-6902 ops.
When it happens
Trigger: A patch file's top-level JSON is not an object — it is an array, a bare string/number, or malformed such that fromJson does not yield a JsonValue.
Common situations: Hand-edited patch with wrong top-level shape; patch generated by tooling emitting an array of ops; syntax error causing unexpected parse result.
Related errors
- SectorPresets must have a sector number.
- '${field.field.getName()}' in ${className} is missing! ${obj
- Attribute definitions must be objects, e.g. {heat: 10}
- Unknown status effect: '
- Unknown unit command name:
AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14).
Data as JSON: /api/errors/05baf39d378dbd2e.
Report an issue: GitHub.