{"record":{"id":"690d58df915c487f","repo":"egametang/ET","slug":"tile-index-too-high","errorCode":null,"errorMessage":"Tile index too high","messagePattern":"Tile index too high","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.recast/Scripts/Core/Share/Detour/DtNavMesh.cs","lineNumber":489,"sourceCode":"            if (lastRef == 0)\n            {\n                // Make sure we could allocate a tile.\n                if (0 == availableTiles.Count)\n                {\n                    throw new Exception(\"Could not allocate a tile\");\n                }\n\n                tile = availableTiles.First?.Value;\n                availableTiles.RemoveFirst();\n                m_tileCount++;\n            }\n            else\n            {\n                // Try to relocate the tile to specific index with same salt.\n                int tileIndex = DecodePolyIdTile(lastRef);\n                if (tileIndex >= m_maxTiles)\n                {\n                    throw new Exception(\"Tile index too high\");\n                }\n\n                // Try to find the specific tile id from the free list.\n                DtMeshTile target = m_tiles[tileIndex];\n                // Remove from freelist\n                if (!availableTiles.Remove(target))\n                {\n                    // Could not find the correct location.\n                    throw new Exception(\"Could not find tile\");\n                }\n\n                tile = target;\n                // Restore salt.\n                tile.salt = DecodePolyIdSalt(lastRef);\n            }\n\n            tile.data = data;\n            tile.flags = flags;","sourceCodeStart":471,"sourceCodeEnd":507,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.recast/Scripts/Core/Share/Detour/DtNavMesh.cs#L471-L507","documentation":"When AddTile is called with a non-zero lastRef (restore a previously removed tile at its old slot), the decoded tile index is bounds-checked against m_maxTiles. An index at or beyond capacity means the ref did not come from this navmesh (different maxTiles, or corrupt/stale), so the restore is rejected before indexing m_tiles.","triggerScenarios":"Calling AddTile(data, flags, lastRef) with a lastRef obtained from a different DtNavMesh, a ref held across a mesh rebuild with smaller maxTiles, or a corrupted/truncated ref.","commonSituations":"Persisting tile refs and reloading into a mesh with different params; sharing refs between meshes; refs from a prior session whose mesh config changed.","solutions":["Only pass a lastRef produced by the same DtNavMesh in its current lifetime; pass 0 for a fresh allocation when unsure.","Do not persist refs across mesh reconfigurations; re-derive them on load.","If streaming with restore, keep maxTiles stable across rebuilds or invalidate cached refs when it changes."],"exampleFix":"// before: ref from another mesh / session\nmesh.AddTile(data, flags, persistedRef);\n\n// after: fresh allocation when the ref's provenance is uncertain\nmesh.AddTile(data, flags, 0);","handlingStrategy":"validation","validationCode":"// Only restore with a ref from this mesh; otherwise allocate fresh\nint idx = DecodePolyIdTile(lastRef); // helper if accessible\nif (lastRef != 0 && idx >= meshMaxTiles)\n    throw new ArgumentOutOfRangeException(nameof(lastRef), \"lastRef index exceeds mesh maxTiles\");\nmesh.AddTile(data, flags, provenanceUncertain ? 0 : lastRef);","typeGuard":null,"tryCatchPattern":"try { return mesh.AddTile(data, flags, lastRef); }\ncatch (Exception e) when (e.Message == \"Tile index too high\")\n{ /* ref is foreign/stale; fall back to a fresh allocation */ return mesh.AddTile(data, flags, 0); }","preventionTips":["Pass lastRef only when it came from this DtNavMesh in its current lifetime.","Do not persist refs across mesh reconfigurations.","Keep maxTiles stable when streaming with restore, or invalidate refs on change."],"tags":["validation","detour-navmesh","stale-ref"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}