Anuken/Mindustry · error · IllegalArgumentException

Invalid unit type: '${value.asString()}'. Must be 'flying/me

Error message

Invalid unit type: '${value.asString()}'. Must be 'flying/mech/legs/naval/payload/missile/tether/crawl'.

What it means

unitType() switches on the "type" string to pick the entity constructor. The default branch throws. NOTE: the error message lists only 'flying/mech/legs/naval/payload/missile/tether/crawl', but the switch ALSO accepts 'tank' and 'hover' — the message is stale/misleading and omits two valid options.

Source

Thrown at core/src/mindustry/mod/ContentParser.java:899

            read(() -> readFields(entry, value));
            return entry;
        }
    );

    Prov<Unit> unitType(JsonValue value){
        if(value == null) return UnitEntity::create;
        return switch(value.asString()){
            case "flying" -> UnitEntity::create;
            case "mech" -> MechUnit::create;
            case "legs" -> LegsUnit::create;
            case "naval" -> UnitWaterMove::create;
            case "payload" -> PayloadUnit::create;
            case "missile" -> TimedKillUnit::create;
            case "tank" -> TankUnit::create;
            case "hover" -> ElevationMoveUnit::create;
            case "tether" -> BuildingTetherPayloadUnit::create;
            case "crawl" -> CrawlUnit::create;
            default -> throw new IllegalArgumentException("Invalid unit type: '" + value.asString() + "'. Must be 'flying/mech/legs/naval/payload/missile/tether/crawl'.");
        };
    }

    private String getString(JsonValue value, String key){
        if(value.has(key)){
            return value.getString(key);
        }else{
            throw new IllegalArgumentException("You are missing a \"" + key + "\". It must be added before the file can be parsed.");
        }
    }

    private String getType(JsonValue value){
        return getString(value, "type");
    }

    private <T extends Content> T find(ContentType type, String name){
        Content c = Vars.content.getByName(type, name);
        if(c == null && currentMod != null) c = Vars.content.getByName(type, currentMod.name + "-" + name);

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Use one of the actually-supported types: flying, mech, legs, naval, payload, missile, tank, hover, tether, crawl.
  2. Check for typos against the switch in ContentParser.java:888-899 (the source of truth, not the message).
  3. Report/ignore the message's omission of tank and hover.

Example fix

// before
"type": "walker"
// after
"type": "legs"
Defensive patterns

Strategy: validation

Validate before calling

// Validate against the TRUE supported set (includes tank/hover, unlike the message).
Set<String> valid = Set.of("flying","mech","legs","naval","payload","missile","tank","hover","tether","crawl");
JsonValue t = value.get("type");
if(t != null && t.isString() && !valid.contains(t.asString())){
    throw new IllegalStateException("Unsupported unit type '" + t.asString() + "'");
}

Type guard

boolean isUnitType(String s){
    return Set.of("flying","mech","legs","naval","payload","missile","tank","hover","tether","crawl").contains(s);
}

Prevention

When it happens

Trigger: A unit JSON "type" value matches none of the switch cases. Note 'tank' and 'hover' actually work despite being absent from the message.

Common situations: Typo in the type string; using an unsupported type name; trusting the error message's list and believing 'tank'/'hover' are invalid when they are valid.

Related errors


AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14). Data as JSON: /api/errors/d1e4bc3721948b09. Report an issue: GitHub.