{"record":{"id":"05baf39d378dbd2e","repo":"Anuken/Mindustry","slug":"patch-must-be-a-json-object","errorCode":null,"errorMessage":"Patch must be a JSON object.","messagePattern":"Patch must be a JSON object\\.","errorType":"validation","errorClass":"SerializationException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/mod/DataPatcher.java","lineNumber":231,"sourceCode":"                        if(cont.minfo.asset != null) cont.minfo.asset.errored = true;\n                        parser.markError(cont, dpMod, cont.minfo.sourceFile, t);\n                    }\n                }\n            }\n\n            if(reloadContentWorld) fixContentArrays();\n        }\n\n        var patchIt = patches.iterator();\n        while(patchIt.hasNext()){\n            PatchAsset set = patchIt.next();\n\n            set.warnings.clear();\n            set.error = false;\n\n            try{\n                Object someValue = parser.getJson().fromJson(null, Jval.read(set.patch).toString(Jformat.plain));\n                if(!(someValue instanceof JsonValue value)) throw new SerializationException(\"Patch must be a JSON object.\");\n\n                if(Vars.state.rules.planet != null && value.has(\"requiredPlanets\")){\n                    JsonValue req = value.get(\"requiredPlanets\");\n                    value.remove(\"requiredPlanets\");\n\n                    //this should be ignored unless this instance is a dedicated server\n                    if(Vars.headless){\n                        String[] planets = req.isArray() ? req.asStringArray() : new String[]{req.asString()};\n                        if(!Structs.contains(planets, Vars.state.rules.planet.name)){\n                            patchIt.remove();\n                            continue;\n                        }\n                    }\n                }\n\n                set.json = value;\n                currentlyApplyingPatch = set;\n                visitStack.clear();","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/mod/DataPatcher.java#L213-L249","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-edited patch with wrong top-level shape; patch generated by tooling emitting an array of ops; syntax error causing unexpected parse result.","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."],"exampleFix":"// before (patch.json)\n[ { \"op\": \"replace\", \"path\": \"a\", \"value\": 1 } ]\n\n// after\n{ \"a\": 1 }","handlingStrategy":"validation","validationCode":"// Ensure a patch is a JSON object before applying.\nObject parsed = parser.getJson().fromJson(null, Jval.read(patch).toString(Jformat.plain));\nif(!(parsed instanceof JsonValue v) || !v.isObject()) {\n    throw new SerializationException(\"Patch must be a JSON object.\");\n}","typeGuard":"boolean isJsonObjectPatch(String json){\n    try {\n        Object p = parser.getJson().fromJson(null, Jval.read(json).toString(Jformat.plain));\n        return p instanceof JsonValue v && v.isObject();\n    } catch(Exception e){ return false; }\n}","tryCatchPattern":"try {\n    DataPatcher.apply(patch);\n} catch(SerializationException e) {\n    if(e.getMessage().equals(\"Patch must be a JSON object.\")) { /* rewrite patch root as object */ }\n    else throw e;\n}","preventionTips":["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."],"tags":["modding","patching","json","validation"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}