egametang/ET · error · IOException
Invalid version
Error message
Invalid version
What it means
After the magic check passes, DtTileCacheLayerHeaderReader.Read verifies the version int equals DT_TILECACHE_VERSION (currently 1). A different version means the layer was written by an incompatible (newer or older) format that this reader cannot parse safely. Thrown as IOException.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Detour.TileCache/Io/DtTileCacheLayerHeaderReader.cs:37
*/
using System.IO;
using DotRecast.Core;
namespace DotRecast.Detour.TileCache.Io
{
public class DtTileCacheLayerHeaderReader
{
public DtTileCacheLayerHeader Read(RcByteBuffer data, bool cCompatibility)
{
DtTileCacheLayerHeader header = new DtTileCacheLayerHeader();
header.magic = data.GetInt();
header.version = data.GetInt();
if (header.magic != DtTileCacheLayerHeader.DT_TILECACHE_MAGIC)
throw new IOException("Invalid magic");
if (header.version != DtTileCacheLayerHeader.DT_TILECACHE_VERSION)
throw new IOException("Invalid version");
header.tx = data.GetInt();
header.ty = data.GetInt();
header.tlayer = data.GetInt();
header.bmin.x = data.GetFloat();
header.bmin.y = data.GetFloat();
header.bmin.z = data.GetFloat();
header.bmax.x = data.GetFloat();
header.bmax.y = data.GetFloat();
header.bmax.z = data.GetFloat();
header.hmin = data.GetShort() & 0xFFFF;
header.hmax = data.GetShort() & 0xFFFF;
header.width = data.Get() & 0xFF;
header.height = data.Get() & 0xFF;
header.minx = data.Get() & 0xFF;
header.maxx = data.Get() & 0xFF;View on GitHub (pinned to 5cab01f7a8)
Solutions
- Re-bake/re-export the tile-cache layers with the DotRecast version that will load them.
- Pin producer and consumer to the same DotRecast version in your asset pipeline.
- If you must migrate, write a one-time converter that reads the old version and writes the current one.
Example fix
// before: layers baked on DotRecast 1.x loaded by 2.x var layer = builder.DecompressTileCacheLayer(comp, oldBytes, order, cCompat); // after: re-bake with the consuming version (or run a migration converter) // re-export layers so header.version == DtTileCacheLayerHeader.DT_TILECACHE_VERSION
Defensive patterns
Strategy: try-catch
Validate before calling
int v = buf.GetInt(); // after magic
if (v != DtTileCacheLayerHeader.DT_TILECACHE_VERSION)
throw new InvalidDataException($"unsupported layer version {v} (expected {DtTileCacheLayerHeader.DT_TILECACHE_VERSION})"); Try / catch
try { header = reader.Read(buf, cCompat); }
catch (IOException e) when (e.Message == "Invalid version")
{ /* re-bake layer with the current DotRecast version */ } Prevention
- Pin producer and consumer DotRecast versions in the asset pipeline.
- Re-bake layers after a version bump.
- Write a migration converter if old layers must be supported.
When it happens
Trigger: Reading a tile-cache layer produced by a different DotRecast/recast4j version whose DT_TILECACHE_VERSION differs; partially overwritten bytes where the version int is corrupt after a valid magic.
Common situations: Upgrading DotRecast across a version bump that changed the layer format; loading caches baked on another toolchain/version; cross-version asset pipelines.
Related errors
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/3f6840204554a978.
Report an issue: GitHub.