Anuken/Mindustry · error · IllegalArgumentException
Two content objects defined with the same name: '{content.na
Error message
Two content objects defined with the same name: '{content.name}' What it means
Thrown by ContentLoader.handleMappableContent when a second MappableContent is registered with a name that already exists in the same ContentType bucket. ContentLoader keys every block/item/liquid/unit-type/etc. by unique name so it can resolve them later by name; a duplicate name makes the registry ambiguous. On collision it also pops the offending (last-pushed) entry off the content list so an invalid object is not left registered. This fires during content loading, so it is almost always a startup-time crash.
Source
Thrown at core/src/mindustry/core/ContentLoader.java:197
public void setCurrentMod(@Nullable LoadedMod mod){
this.currentMod = mod;
}
public String transformName(String name){
return currentMod == null ? name : currentMod.name + "-" + name;
}
public void handleMappableContent(MappableContent content){
if(contentNameMap[content.getContentType().ordinal()].containsKey(content.name)){
var list = contentMap[content.getContentType().ordinal()];
//this method is only called when registering content, and after handleContent.
//If this is the last registered content, and it is invalid, make sure to remove it from the list to prevent invalid stuff from being registered
if(list.size > 0 && list.peek() == content){
list.pop();
}
throw new IllegalArgumentException("Two content objects defined with the same name: '" + content.name + "'");
}
if(currentMod != null){
content.minfo.mod = currentMod;
if(content.minfo.sourceFile == null){
content.minfo.sourceFile = new Fi(content.name);
}
}
contentNameMap[content.getContentType().ordinal()].put(content.name, content);
nameMap.put(content.name, content);
}
public void setTemporaryMapper(MappableContent[][] temporaryMapper){
this.temporaryMapper = temporaryMapper;
}
/** @return the last registered content with the specified name. Note that the content loader makes no attempt to resolve name conflicts. This method can be unreliable. */
public @Nullable MappableContent byName(String name){
return nameMap.get(name);View on GitHub (pinned to f695ad7e60)
Solutions
- Inspect the full stack trace to find which mod/content calls handleMappableContent for the duplicated name (the name is in the message).
- Rename the offending content in your mod so its final name is unique, OR ensure the mod prefix differs (the loader prefixes modded names with currentMod.name + '-').
- If two mods collide, disable one or contact the author; load order does not fix a true name clash.
- If you control both, namespace your content names by mod id (e.g. 'mymod-copper-wall') rather than reusing vanilla names.
Example fix
// before (mod redefines a vanilla name)
content.register(new Wall("copper-wall"){{...}}); // collides with vanilla
// after
content.register(new Wall("mymod-copper-wall"){{...}}); Defensive patterns
Strategy: validation
Validate before calling
// before registering, check the loader for an existing name
if(Vars.content.getByName(content.getContentType(), content.name) != null){
throw new IllegalStateException("Content name already in use: " + content.name);
} Prevention
- Namespace all modded content names with the mod id to avoid clashing with vanilla or other mods.
- Never reuse vanilla content names; pick a distinct final name.
- During mod development, run with only your mod enabled to isolate collisions.
- Grep your content registration calls for duplicate literal names.
When it happens
Trigger: Calling content registration for two MappableContent objects that resolve to the same final name (mod prefix + name) within the same ContentType. Concretely: a mod re-declares a vanilla block name, two mods use the same content name without distinct prefixes, or the same content is registered twice (double init). The check is contentNameMap[contentType].containsKey(content.name).
Common situations: A mod author overrides/renames a vanilla block to its existing name; two enabled mods each define a block named 'copper-wall'; a custom ContentType registration loop runs twice due to a mod loader bug; merging content packs causes collisions. The mod prefix (currentMod.name + '-') only disambiguates when one of the two is modded.
Related errors
- No constructor set up for unit '@': Assign `constructor = [y
- Invalid class ID for `@` detected (found: @). Potential fixe
- Attribute definitions must be objects, e.g. {heat: 10}
- Unknown status effect: '
- Unknown unit command name:
AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14).
Data as JSON: /api/errors/1a1f326634928eeb.
Report an issue: GitHub.