egametang/ET · error · Exception
Invalid tile index
Error message
Invalid tile index
What it means
After decoding a tile ref into its index, RemoveTile checks the index against maxTiles. A decoded index at or beyond the array bound means the ref did not originate from this cache (different capacity, or corrupt/stale bytes). The cache refuses to dereference m_tiles[tileIndex] to avoid an out-of-bounds access.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Detour.TileCache/DtTileCache.cs:297
}
private int Align4(int i)
{
return (i + 3) & (~3);
}
public void RemoveTile(long refs)
{
if (refs == 0)
{
throw new Exception("Invalid tile ref");
}
int tileIndex = DecodeTileIdTile(refs);
int tileSalt = DecodeTileIdSalt(refs);
if (tileIndex >= m_params.maxTiles)
{
throw new Exception("Invalid tile index");
}
DtCompressedTile tile = m_tiles[tileIndex];
if (tile.salt != tileSalt)
{
throw new Exception("Invalid tile salt");
}
// Remove tile from hash lookup.
int h = DtNavMesh.ComputeTileHash(tile.header.tx, tile.header.ty, m_tileLutMask);
DtCompressedTile prev = null;
DtCompressedTile cur = m_posLookup[h];
while (cur != null)
{
if (cur == tile)
{
if (prev != null)
{View on GitHub (pinned to 5cab01f7a8)
Solutions
- Do not exchange tile refs between DtTileCache instances; look up fresh via GetTileRef(tx,ty,layer) on the target cache.
- Treat refs as ephemeral per cache lifetime; do not persist them across config changes.
- Before removing, verify the ref still resolves: GetTileRef by position and compare.
Example fix
// before: ref came from another cache / a previous session cache.RemoveTile(persistedRef); // after: resolve against the current cache by position long ref = cache.GetTileRef(tx, ty, layer); if (ref != 0) cache.RemoveTile(ref);
Defensive patterns
Strategy: validation
Validate before calling
// Resolve the ref against THIS cache by position before removing long ref = cache.GetTileRef(tx, ty, layer); if (ref == 0) return; cache.RemoveTile(ref);
Try / catch
try { cache.RemoveTile(ref); }
catch (Exception e) when (e.Message.Contains("Invalid tile index"))
{ /* ref is foreign/stale; re-resolve by position or drop it */ } Prevention
- Never share tile refs between DtTileCache instances.
- Treat refs as ephemeral per cache lifetime.
- Resolve refs by position right before use.
When it happens
Trigger: Passing a ref obtained from a different DtTileCache instance (whose maxTiles/tileBits differ); a ref corrupted in serialization or truncated; a ref from a cache that was rebuilt with a smaller maxTiles.
Common situations: Sharing tile refs across caches/levels; persisting a ref to disk and reloading into a cache with different params; copying a ref between sessions where the world config changed.
Related errors
- Invalid tile salt
- Invalid tile ref
- Tile index too high
- Item cannot be null
- MethodHook:targetMethod and replacementMethod and proxyMetho
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/0cb7b2601b397db4.
Report an issue: GitHub.