egametang/ET · error · Exception
Invalid tile ref
Error message
Invalid tile ref
What it means
DtTileCache.RemoveTile refuses a reference of 0 because zero is the library's sentinel for 'no tile' (a real tile ref always carries a non-zero salt/index encoding). Passing 0 means the caller never had, or already lost, the reference and there is nothing to remove.
Source
Thrown at Packages/cn.etetet.recast/Scripts/Core/Share/Detour.TileCache/DtTileCache.cs:290
// Init tile.
tile.header = header;
tile.data = data;
tile.compressed = Align4(buf.Position());
tile.flags = flags;
return GetTileRef(tile);
}
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;View on GitHub (pinned to 5cab01f7a8)
Solutions
- Guard the call: only RemoveTile when refs != 0.
- Reset your stored ref to 0 after a successful RemoveTile so a repeated unload is a no-op.
- Log when you attempt to remove a 0 ref so stale unload requests are visible.
Example fix
// before
cache.RemoveTile(storedRef);
// after
if (storedRef != 0)
{
cache.RemoveTile(storedRef);
storedRef = 0;
} Defensive patterns
Strategy: validation
Validate before calling
if (tileRef == 0) return; // nothing to remove cache.RemoveTile(tileRef);
Type guard
static bool IsValidTileRef(long r) => r != 0;
Prevention
- Zero your stored ref after a successful RemoveTile.
- Guard every RemoveTile call with a non-zero check.
- Log attempts to remove a zero ref to catch missing-load bugs upstream.
When it happens
Trigger: Calling RemoveTile(0) directly; passing a ref returned as 0 from a failed AddTile/GetTileRef; removing a tile whose ref was never captured or was reset to default.
Common situations: Unloading a tile from a ref field that defaulted to 0 because load failed earlier; double-unload where the second call still holds the now-zeroed ref; code that assumes GetTileRef always returns a valid handle.
Related errors
- Invalid tile index
- Invalid tile salt
- Tile already exists
- ERR_LocationLockTokenMismatch
- Item cannot be null
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/a5bd384082af2cbd.
Report an issue: GitHub.