Anuken/Mindustry · error · IllegalArgumentException

No constructor set up for unit '@': Assign `constructor = [y

Error message

No constructor set up for unit '@': Assign `constructor = [your unit constructor]`. Vanilla defaults are:
  "flying": UnitEntity::create
  "mech": MechUnit::create
  "legs": LegsUnit::create
  "naval": UnitWaterMove::create
  "payload": PayloadUnit::create
  "missile": TimedKillUnit::create
  "tank": TankUnit::create
  "hover": ElevationMoveUnit::create
  "tether": BuildingTetherPayloadUnit::create
  "crawl": CrawlUnit::create

What it means

UnitType.checkEntityMapping requires a non-null constructor (the entity factory, e.g. UnitEntity::create) so the unit type can spawn entities. If constructor is null it throws IllegalArgumentException listing the vanilla defaults keyed by movement type. This runs during content init.

Source

Thrown at core/src/mindustry/type/UnitType.java:854

        }

        var reqs = getFirstRequirements();

        if(reqs != null){
            stats.add(Stat.buildCost, StatValues.items(reqs));
        }

        if(weapons.any()){
            stats.add(Stat.weapons, StatValues.weapons(this, weapons));
        }

        if(immunities.size > 0){
            stats.add(Stat.immunities, StatValues.statusEffects(immunities.toSeq().sort()));
        }
    }

    protected void checkEntityMapping(Unit example){
        if(constructor == null) throw new IllegalArgumentException(Strings.format("""
            No constructor set up for unit '@': Assign `constructor = [your unit constructor]`. Vanilla defaults are:
              "flying": UnitEntity::create
              "mech": MechUnit::create
              "legs": LegsUnit::create
              "naval": UnitWaterMove::create
              "payload": PayloadUnit::create
              "missile": TimedKillUnit::create
              "tank": TankUnit::create
              "hover": ElevationMoveUnit::create
              "tether": BuildingTetherPayloadUnit::create
              "crawl": CrawlUnit::create
            """, name));

        // Often modders improperly only sets `constructor = ...` without mapping. Try to mitigate that.
        // In most cases, if the constructor is a Vanilla class, things should work just fine.
        if(EntityMapping.map(name) == null) EntityMapping.nameMap.put(name, constructor);

        // Sanity checks; this is an EXTREMELY COMMON pitfalls Java modders fall into.

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Assign a constructor matching your unit's movement type (see the listed defaults).
  2. For custom entity classes, register an entity mapping and supply your own factory.
  3. Set constructor in code if defining the UnitType programmatically.

Example fix

// before
public class MyUnitType extends UnitType {
    public MyUnitType(String name){ super(name); } // constructor null -> throws
}

// after
public class MyUnitType extends UnitType {
    public MyUnitType(String name){
        super(name);
        constructor = UnitEntity::create;
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every UnitType has a constructor before init.
if(unitType.constructor == null) {
    throw new IllegalArgumentException("UnitType '" + unitType.name + "' has no constructor");
}

Type guard

boolean hasConstructor(UnitType t){ return t != null && t.constructor != null; }

Try / catch

try {
    type.checkEntityMapping(example);
} catch(IllegalArgumentException e) {
    if(e.getMessage().startsWith("No constructor set up for unit")) { /* assign constructor */ }
    else throw e;
}

Prevention

When it happens

Trigger: A UnitType is defined (JSON or code) without assigning constructor before checkEntityMapping runs.

Common situations: Custom unit type with no constructor field; JSON omits the constructor; subclass forgets to set it in its constructor/init.

Related errors


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