Random failure to load PackedScenes

Godot Version

v4.2.2.stable.mono.official [15073afe3]


Getting rare but persistent crash reports from players, and when exploring their logs, finding this:

USER ERROR: Condition "!sdata.is_valid()" is true. Returning: nullptr
   at: SceneState::instantiate (scene\resources\packed_scene.cpp:220)

and once, a more specific version of the same sort of thing:

USER ERROR: Index nprops[j].value = 658 is out of bounds (prop_count = 329).
   at: SceneState::instantiate (scene\resources\packed_scene.cpp:291)

The line of code here this occurs:

        Board board = GD.Load<PackedScene>($"res://boards/{Shell.GameBoard}.tscn").Instantiate<Board>();
        if (board == null) {
            FatalError("Could not load board");

Shell.GameBoard is not really variable, it’s always set to one of a couple constants. It’s not the case that the filename is wrong, I know that for sure.

I’m not doing anything fancy there, like, there is no multithreading going on, for example. This really looks like a Godot problem - I find the out-of-bounds error especially disturbing because the id in question is EXACTLY double the max? Weird?

This occurs rarely – too rare for me to ever catch it under a debugger. But enough that it’s clearly gonna cause me issues at release. It’s really starting to freak me out. What could possibly be going wrong? How can I get ANY more info here??

EDIT: Something to note. I actually get “Could not load board” in the log file. Which is interesting - that means that Load() succeeds, but Instantiate() fails. (I guess Load maybe doesn’t do much proactively?)

I made a torture test like this (it runs every frame ,and I do it 10 times in a row per frame just to speed it up)

        for (int i = 0; i < 10; ++i) {
            var scene = ResourceLoader.Load<PackedScene>("res://boards/board.tscn", null, ResourceLoader.CacheMode.Ignore);
            if (scene != null) {
                GD.Print($"TORTURE: Loaded scene");
                try {
                    var node = scene.Instantiate();
                    if (node == null) {
                        GD.Print($"TORTURE: Scene instantiated as null!");
                    } else {
                        GD.Print($"TORTURE: Instantiated node; freeing");
                } catch (Exception e) {
                    GD.Print($"TORTURE: Exception while instantiating scene: {e}");
            } else {
                GD.Print("TORTURE: Could not load scene!!!");

This never triggers in the editor build, but it actually fails in the release build!!!

Here are a variety of the godot errors I see in my logs in the torture test:

USER ERROR: Cannot get class ‘’.
at: ClassDB::instantiate (core\object\class_db.cpp:358)
USER WARNING: Node of type cannot be created. A placeholder will be created instead.
at: SceneState::instantiate (scene\resources\packed_scene.cpp:254)
USER ERROR: Method argument to Callable constructor must be a non-empty string
at: Callable::Callable (core\variant\callable.cpp:334)
USER ERROR: Cannot connect to ‘’: the provided callable is null.
at: Object::connect (core\object\object.cpp:1315)

Based on the torture test, the failure rate is somewhere around maybe 3%, pretty high.

Does this help narrow it down? I guess I can try 4.3 and see if anything is fixed…

Okay, it’s a bit scarier than this. It randomly will NEVER reproduce on certain release builds. I just made another release with some logging changes, and no repro.

Going to experiment some more. If this bug manifests as a result of some build-time event … that’s very scary. Suggests maybe a layout/alignment/ordering problem of some sort? Are builds not deterministic/reproducible??

Update: I have a working build, and a build with the intermittent failure, and I can confirm that there is no difference in the .exe or .pck, only in the game .dll. So this seems possibly C# related. That would make sense with the “Cannot get class ‘’” error seen in the logs.

I have two builds now, one works and one doesn’t. I made tiny inconsequential code changes to perturb two different outputs with no meaningful differences. The only binary difference in the whole app is in my game dll and game pdb. The only semantic difference, per dotPeek, is the perturbations I made. Nevertheless, one fails to reliably load packed scenes, and the other loads them reliably. Given there’s no meaningful semantic difference, I can only assume that there must be some difference in the binary layout somehow. On a binary diff of the two DLL’s, the differences are enormous. dotnet doesn’t seem to produce a very stable layout at all.

Nevertheless, that’s where I’m at. Something in the binary layout of the DLL is broken in random builds for no rhyme or reason.

Confirmed no improvement in Godot mono v4.3-beta2. :frowning:

I’ll try to make a minimal repro, but I’m skeptical… there must be something about my project, like how could PackedScene loading be so flaky “in general”? It hardly seems possible.

If it’s an engine problem then it’s better if you open an issue here Issues · godotengine/godot · GitHub