"Invalid set index 'text' (on base: 'null instance') with value of type 'String'" with @onready

Godot Version

4.1.1

Question

I am getting a crash in my code that I can’t figure out, the error is as follows:
“Invalid set index ‘text’ (on base: ‘null instance’) with value of type ‘String’.” which I thought I avoided by already having @onready with my variables.

Here’s the code that’s going wrong:

#text variables
@onready var food_text: RichTextLabel = $Control/Resources/FoodText

func _ready() → void:
update_stats()

func update_stats():
food_text.text = "Food: " + str(food)

Why am I still getting an error everytime I launch the project?

is the path $Control/Resources/FoodText still correct?

this happen because the food_text is not ready and not assigned, but the _ready() function of this script node call it, so it’s null

add await get_tree().physics_frame before update_stats() to fix the problem

Unfortunately that didn’t work, throws me the same error even adding that in, unless I added it in the wrong place?

func _ready() → void:
await get_tree().physics_frame
update_stats()

func update_stats() → void:
food_text.text = "Food: " + str(food)

Yes it is

so it’s not about the node is ready, can you try this?

@onready var food_text: RichTextLabel = $Resources/FoodText

also show your scene tree for this

also instead of using @onready, try @export instead. it guarantees the node reference to be correct

@export var food_text: RichTextLabel

then assign the food_text node on inspector dock

Still not working, in fact it’s throwing me a whole new errors when I try to add or switch an @export with the @onready

Here’s a screenshot of my editor/scene tree. Yes I know this isn’t the most efficient way to display text, but I’m doing it for style reasons. And unless I’m missing something obvious, it should still work

did anybody other than from _ready() function tried to access the update_stats()? the screenshot show cropped stack trace

i tested similar scene tree and codes, even without the await get_tree().physics_frame, it’s already working, your update_stats() could be accessed somewhere where the node not even ready


Apologies for the late response, and for the cropped screenshot

No other part of the script is calling update_stats() at the start of the game. I’m more than a little baffled because my setup looks just like what you’re doing but I’m getting thrown an error no matter what

Check the scene tree when game is running.
I think it’s because something operated that node.
Scene panel → Remote

no problem, i think let’s just do like this, put

await get_tree().create_timer(3).timeout
update_stats()

in the _ready()
function
see if it still got an error

Okay, this is weird. So the game actually starts, but then crashes at the moment of Timeout with the same error

yeah that’s strange, so accessing the update_stats() function will just result in crashing, what happen if you put the food_text.text= line to the bottom-most of update_stats()?

Same thing, only it crashes on scrap_text instead of food_text

did you try @export instead @onready ?

When I use @export, I get this error:
Parser Error: The default value is using “$” which won’t return nodes in the scene tree before “_ready()” is called. Use the “@onready” annotation to solve this. (Warning treated as error.)

to use @export, do it like this
@export var food_text:RichTextLabel

then click the TheRoom Node, you will see Food Text variable exposed in the Inspector dock, click drag and drop the FoodText RichTextLabel to the Food Text in the Inspector dock, that’s how you assign the FoodText Node with @export

Got the same “invalid set index” error as before when I used that method

even with the await ?

show the already assigned food_text variable in the inspector dock btw, if it’s true you already assigned, with await for like 3 seconds, then something really wrong with your editor