Skip to content

ResourceLoader.load_threaded_request() crashes the engine if called for multiple complicated scenes #111202

Description

@Alexofp

Tested versions

Reproducible in:

Partly reproducible in v4.4.1.stable.official [49a5bc7] (No crashes but there were errors)

System information

Godot v4.4.1.stable - Windows 10 (build 19045) - Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1060 3GB (NVIDIA; 32.0.15.7247) - Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz (4 threads)

Issue description

I have implemented threaded loading of scenes in my game and noticed that I get occasional crashes now during the initial load, especially when there are many things being loaded at once.

I managed to make a MRP that triggers this crash with just one model.

The MRP has a somewhat-complicated head .glb scene that contains multiple rigged meshes with multiple material slots and a handful of animations. If I load this scene synchronously with load(), everything works fine. If I use the provided loadSpawnMesh(), the game crashes on load but only if there are multiple heads being loaded at once

The MRP also has a simple (but high-poly) sphere that seems to load fine no matter how many copies you try to load at once. At least for me.

If I used Godot 4.4.1 stable, the scene mostly loads but I get errors (random each time):

Image Image

Steps to reproduce

2025-10-03.12-21-32.mp4

Here is the code from the MRP:

extends Node3D

const MeshFolderPath = "res://Mesh/"

func _ready() -> void:
	# Crashes
	if(true):
		loadSpawnMesh("res://Mesh/head1.tscn") # Works if you comment other calls out
		loadSpawnMesh("res://Mesh/head2.tscn")
		loadSpawnMesh("res://Mesh/head3.tscn")
		loadSpawnMesh("res://Mesh/head4.tscn")
	
	# Works
	if(false):
		loadSpawnMesh("res://Mesh/BigMesh1.tscn")
		loadSpawnMesh("res://Mesh/BigMesh2.tscn")
		loadSpawnMesh("res://Mesh/BigMesh3.tscn")
		loadSpawnMesh("res://Mesh/BigMesh4.tscn")
	
	#for meshPath in ResourceLoader.list_directory(MeshFolderPath):
		#var finalMeshPath := MeshFolderPath.path_join(meshPath)
		#loadSpawnMesh(finalMeshPath)

func loadSpawnMesh(finalMeshPath:String):
	print("Trying to load: "+str(finalMeshPath))
	var theReq:PackedScene = await loadThreaded(finalMeshPath)
	#var theReq:PackedScene = load(finalMeshPath) # works
	if(!theReq):
		printerr("LOADED RESOURCE IS NULL: "+str(finalMeshPath))
		return
	add_child(theReq.instantiate())
	print("LOADED: "+str(finalMeshPath))

func loadThreaded(_path:String) -> Resource:
	#await get_tree().process_frame #Makes the 'Trying to load X' print show up
	
	if(ResourceLoader.has_cached(_path)):
		return ResourceLoader.load(_path)
	
	var err:= ResourceLoader.load_threaded_request(_path)
	if(err != OK):
		printerr("ERROR! "+error_string(err))
		return null
	
	var loadStatus := ResourceLoader.load_threaded_get_status(_path)
	while(loadStatus == ResourceLoader.THREAD_LOAD_IN_PROGRESS):
		await get_tree().process_frame
		loadStatus = ResourceLoader.load_threaded_get_status(_path)
	
	if(loadStatus != ResourceLoader.THREAD_LOAD_LOADED):
		printerr("FAILED TO LOAD! loadStatus="+str(loadStatus))
		return null
	
	return ResourceLoader.load_threaded_get(_path)

Minimal reproduction project (MRP)

threadedloadcrash_2025-10-03_12-31-50.zip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions