{"record":{"id":"e5c2b554fbc32b60","repo":"Anuken/Mindustry","slug":"field-field-getname-in-classname-is-miss","errorCode":null,"errorMessage":"'${field.field.getName()}' in ${className} is missing! ${object}.${field.field.getName()} cannot be null.","messagePattern":"'(.+?)' in (.+?) is missing! (.+?)\\.(.+?) cannot be null\\.","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/mod/ContentParser.java","lineNumber":1253,"sourceCode":"        }\n    }\n    Object fieldOpt(Class<?> type, JsonValue value){\n        try{\n            return type.getField(value.asString()).get(null);\n        }catch(Exception e){\n            return null;\n        }\n    }\n\n    void checkNullFields(Object object){\n        if(object == null || object instanceof Number || object instanceof String || toBeParsed.contains(object) || object.getClass().getName().startsWith(\"arc.\")) return;\n\n        parser.getFields(object.getClass()).values().toSeq().each(field -> {\n            try{\n                if(field.field.getType().isPrimitive()) return;\n\n                if(!field.field.isAnnotationPresent(Nullable.class) && field.field.get(object) == null && !implicitNullable.contains(field.field.getType())){\n                    throw new RuntimeException(\"'\" + field.field.getName() + \"' in \" +\n                        ((object.getClass().isAnonymousClass() ? object.getClass().getSuperclass() : object.getClass()).getSimpleName()) +\n                        \" is missing! \" + object + \".\" + field.field.getName() + \" cannot be null.\");\n                }\n            }catch(Exception e){\n                throw new RuntimeException(e);\n            }\n        });\n    }\n\n    private void readFields(Object object, JsonValue jsonMap, boolean stripType){\n        if(stripType) jsonMap.remove(\"type\");\n        readFields(object, jsonMap);\n    }\n\n    void readFields(Object object, JsonValue jsonMap){\n        if(!jsonMap.isObject()) throw new SerializationException(\"Expecting an object, but found: '\" + jsonMap + \"'\");\n        JsonValue research = jsonMap.remove(\"research\");\n","sourceCodeStart":1235,"sourceCodeEnd":1271,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/mod/ContentParser.java#L1235-L1271","documentation":"After ContentParser reads mod JSON into a content object it walks every reflective field and rejects any that is null, not annotated @Nullable, not in the implicitNullable allow-list, and not primitive. This enforces that a mod's JSON fully populates the required fields of the target content class (Block, Item, Liquid, etc.). The message names the exact missing field and class.","triggerScenarios":"A mod content JSON entry omits a required field that has no default and no @Nullable annotation. Triggered during the content-parsing pass that follows field reading, via checkNullFields(object) called on the parsed instance.","commonSituations":"Mod author forgets a mandatory field; mod targets an older game version whose schema changed (a field became required); typo in a field name so it is silently ignored and left null; referencing a content type whose Java default is null.","solutions":["Read the message: it states 'FIELD in CLASS is missing'. Add that exact field to your JSON entry.","Confirm the field name spelling and that it is not a removed/renamed field in your game version.","If the field is genuinely optional for your content, the fix belongs in source (annotate the field @Nullable) — not in user JSON.","Re-test by loading only your mod to isolate the entry causing the failure."],"exampleFix":"// before (mod json, incomplete)\n{\n  \"type\": \"Item\",\n  \"name\": \"my-item\",\n  \"color\": \"ff0000\"\n}\n// error: 'hardness in Item is missing! ...'\n\n// after\n{\n  \"type\": \"Item\",\n  \"name\": \"my-item\",\n  \"color\": \"ff0000\",\n  \"hardness\": 0\n}","handlingStrategy":"validation","validationCode":"// Before relying on a parsed content object, ensure required fields are populated.\nfor(Field f : obj.getClass().getDeclaredFields()){\n    f.setAccessible(true);\n    if(!f.getType().isPrimitive()\n       && !f.isAnnotationPresent(Nullable.class)\n       && f.get(obj) == null){\n        throw new IllegalStateException(\"Required field null: \" + f.getName());\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    parser.parse(...);\n} catch(RuntimeException e) {\n    if(e.getMessage() != null && e.getMessage().contains(\"is missing!\")) {\n        // surface field name to user for correction\n    } else throw e;\n}","preventionTips":["Keep mod JSON in sync with the target game version's content schema.","Annotate genuinely-optional source fields with @Nullable.","Validate mod JSON against required fields before publishing."],"tags":["modding","content-parsing","json","reflection","validation"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}