Anuken/Mindustry · error · IOException

Invalid asset type ID: {}. You are likely loading trying to

Error message

Invalid asset type ID: {}. You are likely loading trying to load a save from a newer version of the game, possibly a beta.

What it means

In SaveVersion.readDataPatches (v11+ saves), each embedded asset is prefixed by a typeId byte that indexes DataAssetType.all. If the byte is negative or >= the registered array length, the asset type is unknown to this build and the save cannot be patched. The message explicitly suggests a newer-version save (often a beta).

Source

Thrown at core/src/mindustry/io/SaveVersion.java:552

        return entityMapping;
    }

    public void readEntities(DataInput stream) throws IOException{
        var mapping = readEntityMapping(stream);
        readTeamBlocks(stream);
        readWorldEntities(stream, mapping);
    }

    public void readDataPatches(DataInput stream, SaveReadState saveState) throws IOException{
        stream.readInt(); //version - ignored for now

        int total = stream.readInt();
        Seq<DataAsset> assets = new Seq<>(total);

        for(int i = 0; i < total; i++){
            byte typeId = stream.readByte();
            if(typeId < 0 || typeId >= DataAssetType.all.length) throw new IOException("Invalid asset type ID: " + typeId + ". You are likely loading trying to load a save from a newer version of the game, possibly a beta.");

            String path = stream.readUTF();
            boolean embedded = stream.readBoolean();
            var type = DataAssetType.all[typeId];
            var asset = type.create();

            asset.setPath(path);

            if(embedded){
                asset.read(stream);
            }else{
                byte[] hash = new byte[32];
                stream.readFully(hash);
                asset.setHash(hash);

                if(!asset.isCached()){
                    //TODO: log this when loading a save
                    Log.warn("Asset @: cache file not found.", asset.path);

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Upgrade the loading build to match (or exceed) the build that wrote the save; DataAssetType.all is populated at content init and grows with version.
  2. If developing, register the missing DataAssetType before load.
  3. Disable loading of saves known to be from a newer branch (gate on SaveMeta build tag).

Example fix

// before
SaveIO.load(file); // Invalid asset type ID

// after
SaveMeta meta = SaveIO.getMeta(SaveIO.fileFor(slot));
if (meta.build > Version.build) {
    ui.showInfo("Save is from a newer build (@); cannot load.", meta.build);
} else {
    SaveIO.load(file);
}
Defensive patterns

Strategy: validation

Validate before calling

SaveMeta meta = SaveIO.getMeta(file);
if (meta.build > Version.build) {
    throw new IllegalStateException("Save build " + meta.build + " newer than current " + Version.build);
}

Type guard

null

Try / catch

try {
    SaveIO.load(file);
} catch (SaveException e) {
    if (String.valueOf(e.getCause()).contains("Invalid asset type ID")) {
        // newer-version save; inform user
    }
}

Prevention

When it happens

Trigger: readDataPatches iterates total assets; a typeId byte written by a newer build whose DataAssetType.all has more entries than the loading build's array. Only fires on the patches region, which is read for version >= 12 (and synthesized for < 11).

Common situations: Loading a beta/bleeding-edge save on a stable build; downgrading across an asset-type schema change; mod that extended DataAssetType and the save was made with it but loaded without.

Related errors


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