{"record":{"id":"a71101d8384e159d","repo":"Anuken/Mindustry","slug":"unit-name-has-an-incorrect-type-types-must-b","errorCode":null,"errorMessage":"Unit '${name}' has an incorrect type. Types must be strings.","messagePattern":"Unit '(.+?)' has an incorrect type\\. Types must be strings\\.","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/mod/ContentParser.java","lineNumber":631,"sourceCode":"\n            return block;\n        },\n        ContentType.unit, (TypeParser<UnitType>)(mod, name, value) -> {\n            readBundle(ContentType.unit, name, value);\n\n            UnitType unit;\n            if(!allowPatching || locate(ContentType.unit, name) == null){\n\n                unit = make(resolve(value.getString(\"template\", \"\"), UnitType.class), mod + \"-\" + name);\n\n                if(value.has(\"template\")){\n                    value.remove(\"template\");\n                }\n\n                var typeVal = value.get(\"type\");\n                if(unit.constructor == null || typeVal != null){\n                    if(typeVal != null && !typeVal.isString()){\n                        throw new RuntimeException(\"Unit '\" + name + \"' has an incorrect type. Types must be strings.\");\n                    }\n\n                    unit.constructor = unitType(typeVal);\n                }\n            }else{\n                unit = locate(ContentType.unit, name);\n            }\n\n            currentContent = unit;\n            read(() -> {\n                unit.beforeParse();\n                //add reconstructor type\n                if(value.has(\"requirements\")){\n                    JsonValue rec = value.remove(\"requirements\");\n\n                    UnitReq req = parser.readValue(UnitReq.class, rec);\n\n                    if(req.block instanceof Reconstructor r){","sourceCodeStart":613,"sourceCodeEnd":649,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/mod/ContentParser.java#L613-L649","documentation":"While constructing a UnitType, if a \"type\" field is present in the JSON but its value is not a JSON string, the parser throws. The \"type\" field selects the unit's entity constructor (flying, mech, legs, etc.), so a non-string value (number, object, array) is unparseable.","triggerScenarios":"A unit JSON provides \"type\": 3 or \"type\": {\"name\":\"flying\"} instead of \"type\": \"flying\". The guard fires only when typeVal != null && !typeVal.isString().","commonSituations":"Confusing \"type\" (entity move type) with \"template\" (parent class); pasting a numeric ID from a lookup table; malformed auto-generated JSON.","solutions":["Make the \"type\" value a string literal matching a supported unit type (see error 92).","Omit \"type\" entirely if the template's default constructor is acceptable.","Validate that \"type\" is a quoted string before submitting the mod."],"exampleFix":"// before\n\"type\": 1\n// after\n\"type\": \"flying\"","handlingStrategy":"validation","validationCode":"JsonValue t = value.get(\"type\");\nif(t != null && !t.isString()){\n    throw new IllegalStateException(\"'type' must be a string, got \" + t.type());\n}","typeGuard":"// Narrow a JsonValue to a string 'type' field.\nString unitType(JsonValue v){\n    JsonValue t = v.get(\"type\");\n    return (t != null && t.isString()) ? t.asString() : null;\n}","tryCatchPattern":null,"preventionTips":["Always quote the \"type\" value in unit JSON.","Distinguish \"type\" (entity type) from \"template\" (parent class)."],"tags":["mindustry","modding","json","content-parser","unit","type-mismatch"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}