egametang/ET · error · IOException

Invalid version {header.version}

Error message

Invalid version {header.version}

What it means

Thrown by DtMeshSetReader.ReadHeader when the set header version is none of the supported values (NAVMESHSET_VERSION, NAVMESHSET_VERSION_RECAST4J_1, NAVMESHSET_VERSION_RECAST4J). The set file was written by a Detour version this reader cannot parse.

Source

Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Detour/Io/DtMeshSetReader.cs:93

        {
            NavMeshSetHeader header = new NavMeshSetHeader();
            header.magic = bb.GetInt();
            if (header.magic != NavMeshSetHeader.NAVMESHSET_MAGIC)
            {
                header.magic = IOUtils.SwapEndianness(header.magic);
                if (header.magic != NavMeshSetHeader.NAVMESHSET_MAGIC)
                {
                    throw new IOException("Invalid magic " + header.magic);
                }

                bb.Order(bb.Order() == RcByteOrder.BIG_ENDIAN ? RcByteOrder.LITTLE_ENDIAN : RcByteOrder.BIG_ENDIAN);
            }

            header.version = bb.GetInt();
            if (header.version != NavMeshSetHeader.NAVMESHSET_VERSION && header.version != NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J_1
                                                                      && header.version != NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J)
            {
                throw new IOException("Invalid version " + header.version);
            }

            header.numTiles = bb.GetInt();
            header.option = paramReader.Read(bb);
            header.maxVertsPerPoly = maxVertsPerPoly;
            if (header.version == NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J)
            {
                header.maxVertsPerPoly = bb.GetInt();
            }

            return header;
        }

        private void ReadTiles(RcByteBuffer bb, bool is32Bit, NavMeshSetHeader header, bool cCompatibility, DtNavMesh mesh)
        {
            // Read tiles.
            for (int i = 0; i < header.numTiles; ++i)
            {

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Re-bake the navmesh set with the current DotRecast/Detour toolchain.
  2. Pin asset producer and runtime to a compatible version.
  3. Inspect the version int in the header and reject unsupported files early.

Example fix

// before
var mesh = setReader.Read(bb); // version mismatch

// after
// re-export set with current toolchain, then:
var mesh = setReader.Read(bb);
Defensive patterns

Strategy: validation

Validate before calling

int v = BitConverter.ToInt32(chunk, 4);
bool ok = v == NavMeshSetHeader.NAVMESHSET_VERSION ||
          v == NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J_1 ||
          v == NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J;
if (!ok) throw new InvalidDataException($"Unsupported set version {v}");

Type guard

static bool IsSupportedSetVersion(int v)
    => v == NavMeshSetHeader.NAVMESHSET_VERSION ||
       v == NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J_1 ||
       v == NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J;

Try / catch

try { var mesh = setReader.Read(bb); }
catch (IOException e) when (e.Message.Contains("Invalid version"))
{ /* re-export set with current toolchain */ }

Prevention

When it happens

Trigger: Loading a navmesh set exported by a newer or older Detour/recast4j build; consuming a set file from an incompatible fork.

Common situations: Package version drift between bake-time and runtime; cross-tool asset sharing.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/109193536790d56a. Report an issue: GitHub.