HMCL-dev/HMCL · error · java.io.IOException

Metadata tag is not a compound tag

Error message

Metadata tag is not a compound tag

What it means

LitematicFile.load() requires the root 'Metadata' tag to be a CompoundTag. This IOException is thrown when a 'Metadata' key exists in the root NBT compound but holds a different tag type (e.g. IntTag, StringTag), making the metadata unusable as a compound.

Solutions

  1. Re-export or re-download the litematic file from a trusted source
  2. Inspect the NBT tree and confirm 'Metadata' is a compound with expected sub-tags (Name, RegionCount, etc.)
  3. Handle the IOException in calling code and surface a 'corrupted file' message to users
  4. If the file was converted by a tool, fix the converter so it writes Metadata as a CompoundTag

Example fix

// before
LitematicFile f = LitematicFile.load(path); // throws on malformed Metadata
// after
try {
    LitematicFile f = LitematicFile.load(path);
} catch (IOException e) {
    LOG.warning("Invalid litematic file: " + e.getMessage());
}
Defensive patterns

Strategy: validation

Validate before calling

Object metadata = root.getValue().get("Metadata");
if (metadata != null && !(metadata instanceof CompoundTag))
    throw new IllegalArgumentException("Metadata tag has wrong NBT type");

Type guard

static boolean hasCompoundMetadata(CompoundTag root) {
    return root.getValue().get("Metadata") instanceof CompoundTag;
}

Try / catch

try {
    LitematicFile f = LitematicFile.load(path);
} catch (IOException e) {
    if (e.getMessage().contains("not a compound tag")) showCorruptFileDialog();
    else throw e;
}

Prevention

When it happens

Trigger: Calling LitematicFile.load(file) on an NBT file where the root's 'Metadata' entry is present but is not a compound — usually from a malformed or tampered file, or an NBT writer that serialized metadata with the wrong type.

Common situations: Hand-edited litematic files; files produced by buggy third-party converters; corruption that overwrote tag types while keeping key names.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/2f701757419d4378. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/schematic/LitematicFile.java:58

    public static LitematicFile load(Path file) throws IOException {

        CompoundTag root;
        try (InputStream in = new GZIPInputStream(Files.newInputStream(file))) {
            root = NBTCodec.of().readTag(in, TagType.COMPOUND);
        }

        Tag versionTag = root.get("Version");
        if (versionTag == null)
            throw new IOException("Version tag not found");
        else if (!(versionTag instanceof IntTag))
            throw new IOException("Version tag is not an integer");

        Tag metadataTag = root.get("Metadata");
        if (metadataTag == null)
            throw new IOException("Metadata tag not found");
        else if (!(metadataTag instanceof CompoundTag))
            throw new IOException("Metadata tag is not a compound tag");

        int regions = 0;
        if (root.get("Regions") instanceof CompoundTag regionsTag)
            regions = regionsTag.size();

        return new LitematicFile(file, (CompoundTag) metadataTag,
                ((IntTag) versionTag).getValue(),
                root.getIntOrZero("SubVersion"),
                root.getIntOrZero("MinecraftDataVersion"),
                regions
        );
    }

    private final @NotNull Path file;

    private final int version;
    private final int subVersion;
    private final int minecraftDataVersion;

View on GitHub (pinned to 24702dc5a0)