{"record":{"id":"55022d19acbe6d97","repo":"egametang/ET","slug":"invalid-version-55022d","errorCode":null,"errorMessage":"Invalid version","messagePattern":"Invalid version","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.recast/Scripts/Core/Share/Detour.TileCache/Io/DtTileCacheReader.cs","lineNumber":64,"sourceCode":"            DtTileCacheSetHeader header = new DtTileCacheSetHeader();\n            header.magic = bb.GetInt();\n            if (header.magic != DtTileCacheSetHeader.TILECACHESET_MAGIC)\n            {\n                header.magic = IOUtils.SwapEndianness(header.magic);\n                if (header.magic != DtTileCacheSetHeader.TILECACHESET_MAGIC)\n                {\n                    throw new IOException(\"Invalid magic\");\n                }\n\n                bb.Order(bb.Order() == RcByteOrder.BIG_ENDIAN ? RcByteOrder.LITTLE_ENDIAN : RcByteOrder.BIG_ENDIAN);\n            }\n\n            header.version = bb.GetInt();\n            if (header.version != DtTileCacheSetHeader.TILECACHESET_VERSION)\n            {\n                if (header.version != DtTileCacheSetHeader.TILECACHESET_VERSION_RECAST4J)\n                {\n                    throw new IOException(\"Invalid version\");\n                }\n            }\n\n            bool cCompatibility = header.version == DtTileCacheSetHeader.TILECACHESET_VERSION;\n            header.numTiles = bb.GetInt();\n            header.meshParams = paramReader.Read(bb);\n            header.cacheParams = ReadCacheParams(bb, cCompatibility);\n            DtNavMesh mesh = new DtNavMesh(header.meshParams, maxVertPerPoly);\n            IRcCompressor comp = _compFactory.Create(cCompatibility ? 0 : 1);\n            DtTileCacheStorageParams storageParams = new DtTileCacheStorageParams(bb.Order(), cCompatibility);\n            DtTileCache tc = new DtTileCache(header.cacheParams, storageParams, mesh, comp, meshProcessor);\n            // Read tiles.\n            for (int i = 0; i < header.numTiles; ++i)\n            {\n                long tileRef = bb.GetInt();\n                int dataSize = bb.GetInt();\n                if (tileRef == 0 || dataSize == 0)\n                {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.recast/Scripts/Core/Share/Detour.TileCache/Io/DtTileCacheReader.cs#L46-L82","documentation":"After the set magic passes, DtTileCacheReader.Read checks the version int. It accepts the current TILECACHESET_VERSION (1) or the legacy recast4j version (0x8801); any other value throws 'Invalid version'. The cCompatibility flag is then derived from which version matched, so a truly unknown version cannot be safely parsed.","triggerScenarios":"Loading a tile-cache set written by a DotRecast/recast4j version whose set version is neither 1 nor 0x8801; bytes whose version int is corrupt after a valid magic.","commonSituations":"Cross-version asset loading after a format change; hand-edited or partially overwritten files; producer and consumer on mismatched library versions.","solutions":["Re-export the tile-cache set with the consuming DotRecast version.","Keep producer and consumer library versions aligned in CI/asset baking.","If migrating from recast4j, confirm the file carries version 0x8801 so the legacy path is used."],"exampleFix":"// before: set baked on an incompatible version\nvar tc = reader.Read(bb, maxVertPerPoly, proc);\n\n// after: re-bake with current version, or verify version up front\nint v = bb.GetInt();\nif (v != DtTileCacheSetHeader.TILECACHESET_VERSION\n && v != DtTileCacheSetHeader.TILECACHESET_VERSION_RECAST4J)\n    throw new InvalidDataException($\"unsupported tilecache set version {v}\");","handlingStrategy":"try-catch","validationCode":"int v = bb.GetInt(); // after magic\nif (v != DtTileCacheSetHeader.TILECACHESET_VERSION\n && v != DtTileCacheSetHeader.TILECACHESET_VERSION_RECAST4J)\n    throw new InvalidDataException($\"unsupported tile-cache set version {v}\");","typeGuard":null,"tryCatchPattern":"try { return reader.Read(bb, maxVertPerPoly, proc); }\ncatch (IOException e) when (e.Message == \"Invalid version\")\n{ /* re-export the set with the current version */ }","preventionTips":["Align producer and consumer DotRecast versions in baking and loading.","Re-bake the set after a library upgrade.","For recast4j imports, confirm the file carries version 0x8801."],"tags":["io","detour-tilecache","serialization","version"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}