Evading GridMap Crashes
It's been another busy streak since the last update including a rework of all the existing levels. In the process of doing this, a not-so-obvious bug revealed itself in Godot.
As mentioned in The Previous Post, several levels were reworked to use new wall meshes. While doing this, some were rearranged slightly and needed some areas of the map to be moved. While doing this, the editor consistently crashed when bulk moving tiles with the following stack trace:
ERROR: Requested for nonexistent MeshLibrary item '1'.
at: get_item_mesh (scene/resources/3d/mesh_library.cpp:221)
================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.4.1.stable.official (49a5bc7b616bd04689a2c89e89bda41f50241464)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /lib/x86_64-linux-gnu/libc.so.6(+0x45810) [0x75d825645810] (??:0)
[2] ~/.local/bin/godot() [0xf9a45b] (??:0)
[3] ~/.local/bin/godot() [0x4513ff4] (??:0)
[4] ~/.local/bin/godot() [0x47d555a] (??:0)
[5] ~/.local/bin/godot() [0x80ba73] (??:0)
[6] ~/.local/bin/godot() [0xff6b76] (??:0)
[7] ~/.local/bin/godot() [0x18d15b6] (??:0)
[8] ~/.local/bin/godot() [0x1fcbfc8] (??:0)
[9] ~/.local/bin/godot() [0x1fa8d7c] (??:0)
[10] ~/.local/bin/godot() [0x47d555a] (??:0)
[11] ~/.local/bin/godot() [0x2a3ac76] (??:0)
[12] ~/.local/bin/godot() [0x2985808] (??:0)
[13] ~/.local/bin/godot() [0x29865b6] (??:0)
[14] ~/.local/bin/godot() [0x299d7bc] (??:0)
[15] ~/.local/bin/godot() [0x4f18ecb] (??:0)
[16] ~/.local/bin/godot() [0x4ced85] (??:0)
[17] ~/.local/bin/godot() [0x442a293] (??:0)
[18] ~/.local/bin/godot() [0x442c14f] (??:0)
[19] ~/.local/bin/godot() [0x4dc1e3] (??:0)
[20] ~/.local/bin/godot() [0x41e7a0] (??:0)
[21] /lib/x86_64-linux-gnu/libc.so.6(+0x2a338) [0x75d82562a338] (??:0)
[22] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x8b) [0x75d82562a3fb] (??:0)
[23] ~/.local/bin/godot() [0x44297a] (??:0)
-- END OF BACKTRACE --
================================================================
As it turns out, when some old items were removed from the mesh library, they hadn't also been removed from the GridMap that was in use first; this leaves a lingering reference in the GridMap to items that no longer exist in the mesh library.
In the below example, you can see we have three distinct meshes; a blue (item 1), a red (item 2) and a green (item 3) cube:

If we leave the GridMap as is, and delete item 2 from the assigned mesh library, the GridMap will visually update to reflect this, as can be seen below, but the cells between the blue and green cells will still reference item 2 of the mesh library.

Even though these items no longer exist in the mesh library and show no visible mesh on the GridMap, the cells containing the invalid references will still attempt to access the item when moving them after selecting an area that contains them, which then causes the crash.
An issue for this has been raised for this on GitHub (which you can track Here), but in the meantime, you can cleanup GridMaps containing invalid items using the script we've created below:
@tool
class_name GridMapCleaner
extends Node
@export_tool_button("Remove Invalid Items", "Callable") var remove_invalid_items_action: Callable = remove_invalid_items
@export var grid_map: GridMap
func remove_invalid_items() -> void:
if not grid_map:
print("GridMapCleaner: GridMap has not been set, aborting.")
return
var mesh_library: MeshLibrary = grid_map.mesh_library
var used_cells: Array[Vector3i] = grid_map.get_used_cells()
for i in range(used_cells.size()):
var cell: Vector3i = used_cells[i]
var item_index: int = grid_map.get_cell_item(cell)
var mesh: Mesh = mesh_library.get_item_mesh(item_index)
if not mesh:
print("GridMapCleaner: Removing invalid mesh ID (", item_index, ") at ", cell)
grid_map.set_cell_item(cell, GridMap.INVALID_CELL_ITEM)
print("GridMapCleaner: Finished removing invalid items.")
To use this tool, create a new GDScript file wherever you prefer to store your tools and paste the above code into it.
Next, go to the scene containing a GridMap that you want to clean of invalid items and add a new GridMapCleaner
node. If you open the GridMapCleaner
node in the inspector, you'll see a "Grid Map" property [1] that you can assign your problematic GridMap to and a button [2] that can be used to remove all the invalid items:

After hitting the Remove Invalid Items
button, you should see a message in the output pane indicating it is complete, and the items should no longer cause the aforementioned crash or any other unexpected issues.