{"record":{"id":"46250677f32a4864","repo":"Anuken/Mindustry","slug":"failed-to-read-tile-entity-of-block-462506","errorCode":null,"errorMessage":"Failed to read tile entity of block: ","messagePattern":"Failed to read tile entity of block: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/io/versions/LegacySaveVersion.java","lineNumber":85,"sourceCode":"                            tile.build.health = stream.readUnsignedShort();\n                            byte packedrot = stream.readByte();\n                            byte team = Pack.leftByte(packedrot) == 8 ? stream.readByte() : Pack.leftByte(packedrot);\n                            byte rotation = Pack.rightByte(packedrot);\n\n                            tile.setTeam(Team.get(team));\n                            tile.build.rotation = rotation;\n\n                            if(tile.build.items != null) tile.build.items.read(in, true);\n                            if(tile.build.power != null) tile.build.power.read(in, true);\n                            if(tile.build.liquids != null) tile.build.liquids.read(in, true);\n                            //skip cons.valid boolean, it's not very important here\n                            stream.readByte();\n\n                            //read only from subclasses!\n                            tile.build.read(in, version);\n                        });\n                    }catch(Throwable e){\n                        throw new IOException(\"Failed to read tile entity of block: \" + block, e);\n                    }\n\n                    context.onReadBuilding();\n                }else{\n                    int consecutives = stream.readUnsignedByte();\n\n                    //air is a waste of time and may mess up multiblocks\n                    if(block != Blocks.air){\n                        for(int j = i + 1; j < i + 1 + consecutives; j++){\n                            context.tile(j).setBlock(block);\n                        }\n                    }\n\n                    i += consecutives;\n                }\n            }\n        }finally{\n            if(!generating) context.end();","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/io/versions/LegacySaveVersion.java#L67-L103","documentation":"LegacySaveVersion reads building data from a very old save using a legacy per-block read path (health, team, rotation, items/power/liquids, then tile.build.read). Any Throwable thrown during that read is wrapped in an IOException naming the offending block. The message identifies which block failed; the wrapped cause carries the real reason.","triggerScenarios":"Loading a legacy save where a building's serialized data is corrupt or in a format the current block class cannot read.","commonSituations":"Loading saves from much older game versions; a mod that changed a block's read/write format since the save was made; partial save corruption.","solutions":["Inspect the wrapped cause (e.getCause()) to find the real failure.","If the save is from an unsupported old version, start a new save.","Update and align mods to the versions that created the save."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    legacyVersion.read(stream, context);\n} catch(IOException e) {\n    Log.err(\"Save load failed for block: \" + e.getMessage(), e.getCause());\n    // e.getMessage() names the block; e.getCause() is the real failure\n}","preventionTips":["Keep mods version-aligned with the saves you load.","For very old saves, prefer exporting/restarting over a direct load.","Always log the wrapped cause (getCause), not just the top-level message."],"tags":["save","legacy","deserialization","migration"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}