Why does assigning a node path to a variable only show null?

I have a function that randomly picks a fish from a list and an AnimatedSprite2d with the same names for animations but I’m getting the error Attempt to call function 'play' in base 'null instance' on a null instance.

I’m pretty sure you’ll need more info to answer this so lmk what else is neccesary

extends Node2D
var rng = RandomNumberGenerator.new()

func weighted_rng(array, weights):
    var number = rng.randi_range(0, 100)
    for weight in weights:
        if weight > number:
            return array[weights.find(weight, 0)]

@onready var bobber = $/Angler/Rod/Bobber
@onready var fish_sprite = $/Angler/Rod/CaughtFish/AnimatedSprite2D

var fishing_pool = ["Tuna", "Clownfish", "Flounder"]
var caught_fish

func _ready():
    pass

func fish():
    caught_fish = fishing_pool[rng.randi_range(0, len(fishing_pool)-1)]
    fish_sprite.play(caught_fish)

Issue Explained

You’re getting this error:

Attempt to call function ‘play’ in base ‘null instance’ on a null instance.

That means this line is failing:

fish_sprite.play(caught_fish)

And specifically, fish_sprite is null when you try to call .play().


Why It’s Happening

You’re using this line:

@onready var fish_sprite = $/Angler/Rod/CaughtFish/AnimatedSprite2D

However, from your scene tree screenshot, it seems that:

  • CaughtFish and AnimatedSprite2D are indeed under Rod
  • But if CaughtFish is not yet added to the scene or is instanced later (e.g. via code), then @onready can’t find it when _ready() runs, so fish_sprite will be null.

Fix Options

Option 1: Ensure CaughtFish Exists at Startup

Make sure that CaughtFish and its child AnimatedSprite2D are already in the scene tree when _ready() runs. If you are instancing it dynamically later, you’ll need to access it after it’s added.

Option 2: Use get_node() at time of use

Instead of caching the node with @onready, directly get it when needed:

func fish():
    caught_fish = fishing_pool[rng.randi_range(0, len(fishing_pool)-1)]
    var fish_sprite = $/Angler/Rod/CaughtFish/AnimatedSprite2D
    fish_sprite.play(caught_fish)

This way, you avoid holding a reference that may be null if the node wasn’t ready yet.


Bonus Tips

Check Animation Names

Make sure that your AnimatedSprite2D node has animations named "Tuna", "Clownfish", "Flounder" — otherwise .play(name) won’t work either.

Use print() to Debug

print(fish_sprite)

before .play() to confirm if it’s null at runtime.