[v4.6.1]Errors - "can_process: Condition "!is_inside_tree()" is true. Returning: false" - How To Locate In Source Code & Fix?

Godot Version

v4.6.1.stable.official [14d19694e] - Linux (CachyOS)

Question

Hi,

Our Godot v4.6.1 game shows below errors occasionally?
E 0:00:25:541 can_process: Condition “!is_inside_tree()” is true. Returning: false
<C++ Source> scene/main/node.cpp:902 @ can_process()

How can we fix the above errors?
It does not point to a line in the GDScript source code?

Let us know, thanks!

1 Like

Your trying to access a node while it is not in the tree.

If you have a script running on the func _ready (not sure) or _init you can have this error so try locate the line .

This is my guess.

First, figure out how to reproduce this bug. Does it happen only when you start the game? Does it happen when you press a certain button, or follow a particular sequence? Pay attention to what you were doing right before this happened.

I’d also recommend trying out Godot 4.6.2-rc2 and see if it gives you a more detailed error message. Try the same with 4.7-dev2, but back up your project first. At some point recently they made it so even C++ errors were supposed to hyperlink back to GDScript code - but I don’t remember which version it was.

I had this error in my menu containing multiple change scene to files. Using call deferred fixed it.

Hi,

Game is 100% GDScript source code with one main scene.

It is occurring with our text management system in two places.
Fixed one already, trying to pinpoint the other.

Should be solved soon, thanks!

Still trying to solve…

Two questions:
(1) Does this error have any bad effects on the running game?
(2) What is “call differed”? And how to use it?

If it doesn’t stop execution, then it’s up to you whether it’s a problem or not. But something isn’t working the way it is supposed to, so sooner or later you’ll find the bug.

call_deferred() is a method in the Object class, which means it can be used by pretty much any object. Click the link for details on how to use it.

Basically it delays that piece of code. Here’s an example how I’ve used it.

get_tree().change_scene_to_file.call_deferred("res://Mainmenu.tscn")

Hi,

I don’t know where to put the “call_deferred()”?
The errors do not point to a line in the GDScript source code?

Uploaded the updated source code to GitHub.

There are two areas I am focused on:
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/VisualsCore.gd#L506
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/VisualsCore.gd#L529

The only time call_deferred() should be used is when you’re in the middle of _physics_process() or _process(). Otherwise, it is better to figure out what has not been created and await the ready Signal for that Object. Otherwise, you are just creating a potential race condition.

All call_deferred() does is make something happen at the end of the current frame.

I can’t get to that error because there are other errors that need addressing.
First off you have a return false inside an _input() function at line 370 in InputCore.gd
That is a virtual function and is defined as not returning a value (->void:)
Easy enough to fix so long as you aren’t depending on a return value:
if ScreensCore.ScreenFadeStatus != ScreensCore.FadingIdle: return #false

If we try to run it we run into another wall with a missing image:
Sprites.SpriteImage[26] = load("res://media/images/gui/NF_GP_QR_Code.png")
Since the file is missing Sprites.SpriteImage[26] end up as null and we get the error:
Attempt to call function 'get_size' in base 'null instance' on a null instance.

However it already reads as an error before running it:
_ready(): Unable to open file: res://.godot/imported/NF_GP_QR_Code.png-

If you fix those up I will try another look at this.

My preliminary look is saying this program is unnecessarily initializing massive resources. There is surely going to be a better approach but I don’t want to go to deep until I get something that at least runs.

Wow, thanks for the help!

I made the bug fixes and uploaded new source to GitHub below:
https://github.com/savantsavior/numbersfall

This version runs and plays the game and I can’t get any error to show up.
I guess that’s good news and bad news. If you can direct me as to how to get the title error to show that would be something to address.
Is it supposed to slow down dropping numbers after the first row?

I suppose we could talk about some code if you would like but I have to be very careful with a working program; I don’t want to talk you into one that no longer works.
I have some questions regarding VisualCore.gd but the main one is why are you initializing 40k member items of the SpriteClass instance?
Why do you want 40k items in memory?

for index in range(30, 40):
		Sprites.SpriteImage[index] = load("res://media/images/gui/ScreenLine2.png")
		Sprites.SpriteActive[index] = true

There are a number of these kind of loops and I think they could disappear entirely but in the mean time you might see some benefit to loading once and using duplicate() and since all Sprites.SpriteActive members are going to begin as true, you could use the .fill() method of the Array type

Sprites.SpriteActive.fill(true)
Sprites.SpriteImage[30] = load("res://media/images/gui/ScreenLine2.png")
for index in range(31, 40):
		Sprites.SpriteImage[index] = Sprites.SpriteImage.duplicate()

I would take every single variable in every script and give them a type.

class SpriteClass:
	#var ci_rid = []
	var ci_rid:Array[RID]
	#var SpriteImage = []
	var SpriteImage:Array[Resource]
	for _index in range(0, 40000):
#		Sprites.ci_rid.append(-1)
		#Sprites.ci_rid[_index] = RenderingServer.canvas_item_create()
		Sprites.ci_rid.append( RenderingServer.canvas_item_create())
		RenderingServer.canvas_item_set_parent(Sprites.ci_rid[_index], get_canvas_item())
		#Sprites.SpriteImage.append(-1)
		Sprites.SpriteImage.append(null)

This is probably going to break some setup that you have but it will give you better error messages and possibly speed things up.

Like I said, I don’t think that initializing 40k elements is necessary.

Hi,

I did most of what you wanted, please have a look:
https://github.com/savantsavior/numbersfall
(took a couple of hours)

”Is it supposed to slow down dropping numbers after the first row?”

  • Yes, that is intended.

I also made all operators( * / + - ) have two tiles on the playfield at all times.

The original errors happen during screen transitions.
Please have a look at below:
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/ScreensCore.gd#L207

If you click on [About] button on title screen and then exit the about(staff) screen it happens?

It is something with the text I believe but I can’t pinpoint it.

Many thanks for your help, much appreciated!

1 Like

The problem is below:

func DeleteAllTexts():

for index in range( (TextCurrentIndex - 1), 9, -1 ):
	if (TextIsUsed[index] == true):
		TextIsUsed[index] = false
		remove_child(Texts.TextImage[index])


TextCurrentIndex = 10

pass


Solved it below, thanks!

func DeleteAllTexts():

for index in range(10, 1000):
	if (TextIsUsed[index] == true):
		TextIsUsed[index] = false
		remove_child(Texts.TextImage[index])


TextCurrentIndex = 10

pass


Sorry, false alarm - still occurring

The version you uploaded to github does not have types set for the variables. It makes it much harder to decipher what your intent is with these variables.
However:
I am able to replicate the error if I let the GodotScreen time out and then hit the about screen and come back.
If I short circuit the screen by clicking on it and then go to about and come back I don’t get the error.

I haven’t found the culprit yet but there is some stuff that needs fixing.

There is a big issue here in ScreensCore.gd

ScreensCore.gd - Line 1939
If you put that print line in you will find this gets run 100’s of times.

	if (ScreenToDisplay != PlayingGameScreen):
		print("x")
		InterfaceCore.DrawAllButtons()
		InterfaceCore.DrawAllArrowSets()   

Worse than that though is that if you put a breakpoint on line 1920 you will see that this code gets run in what appears to be every process frame.

	elif ScreenToDisplay == TitleScreen:
		DisplayTitleScreen()   #line 1920

That needs to be fixed for sure.

It looks like you are using ScreenDisplayTimer as an old fashioned loop count down effectively creating a timer by making the system loop until.
If so, this is wildly backwards. It will not be consistent across different systems.
Godot has a built in timer node that is designed for this purpose. Use that.

There are a number of places where you have an equation rather than a value.
For example ScreensCore.gd - line 275 - use a named constant instead of calculation
ScreenDisplayTimer = (120*2)

This makes the system work harder than it needs to and makes reading your code more difficult.
In these places use a name constant instead.

const  GODOT_SCREEN_DISPLAY_TIME:int = 240    
const FAS_SCREEN_DISPLAY_TIME:int = 120   # or whatever time it actually is
...
ScreenDisplayTimer = GODOT_SCREEN_DISPLAY_TIME

There is a code block that sets ScreenToDisplayNext to FASScreen.
That is index 7 of Sprites.SpriteImage
Sprites.SpriteImage[7] is set to -1 and never changes.
What is FASScreen?
This screen is never used. I guess it is some fading thing you might implement later?

Line 287 ScreensCore.gd

	elif ScreenDisplayTimer == 1:
		ScreenToDisplayNext = FASScreen
		ScreenFadeStatus = FadingToBlack
		ScreenDisplayTimer = -1
		if InputCore.MouseButtonLeftPressed == true || InputCore.KeyboardSpacebarPressed == true || InputCore.JoyButtonOne[InputCore.InputAny] == InputCore.Pressed:  AudioCore.PlayEffect(1)

My guess is that none of this is being used yet except for the mouse click sound.
This isn’t causing an issue as far as I can tell. I am just trying get in tune with what is happening.

Hi,

Working on above changes now…

Do you have a website or a blog or something?
Would like to promote it in the [About] staff screen.
(to thank you for your help with this game)

Let me know, changes are coming soon…

Ready:

https://github.com/savantsavior/numbersfall