Menu

GDScript null and is_instance_valid(): Freed Objects

What null means in GDScript, how to check for it, why a freed node is not the same as null, and when to use is_instance_valid() instead of a null check.

This page includes runnable editors. Edit, run, and see output instantly.

null means "no value". A variable with no value and no type starts as null, and so does any variable that holds an object until you give it one:

<null>
true
No target yet
Target: Node

null counts as false in an if, so if target: reads "if there is a target".

Using a null Value Is an Error

Calling a method or reading a property on null stops the function:

SCRIPT ERROR: Invalid call. Nonexistent function 'jump' in base 'Nil'.
          at: _ready (res://main.gd:7)
          GDScript backtrace (most recent call first):
              [0] _ready (res://main.gd:7)
before

base 'Nil' is Godot telling you the value was null. The usual causes: a $NodePath that does not match the scene, an @onready variable read before _ready(), or a function that returned nothing.

Default Values Instead of null

Dictionaries return null for a missing key with get(), or a default you choose:

<null>
1
Untitled

Freed Objects and is_instance_valid()

When a node is deleted, variables that point at it do not turn into null. They point at a freed object, and using one is an error. is_instance_valid() tells the two apart:

true
true
false
<Freed Object>

queue_free() deletes the node at the end of the frame, which is why the first check is still true. After that, remembered holds a <Freed Object>. Writing to it fails with an error like:

Invalid assignment of property or key 'name' with value of type 'String' on a base object of type 'previously freed'.

When to Use Each Check

SituationCheck
A variable that may never have been setif target == null: or if not target:
A stored reference to a node that may have diedif is_instance_valid(target):
A node that may be leaving this frameif not target.is_queued_for_deletion():

A homing missile is the classic case for is_instance_valid():

var target: Node2D

func _physics_process(delta):
	if not is_instance_valid(target):
		queue_free()  # the target died, so the missile goes too
		return
	position = position.move_toward(target.position, 300 * delta)

An even safer habit is to clear the reference when the node leaves, by connecting to its tree_exiting signal and setting the variable back to null.

Frequently Asked Questions

How do I check for null in GDScript?

Compare with == null: if target == null:. For objects you can also write if target: or if not target:, because null counts as false. Use is_instance_valid(target) when the object may have been freed.

What does is_instance_valid do in Godot?

is_instance_valid(value) returns true when the value is an object that still exists. It returns false for null and for an object that was freed, such as an enemy removed with queue_free(). Calling a method on a freed object is an error, so check before you use a stored reference.

What does "previously freed" mean in Godot?

Your variable still points at an object that has been deleted, usually a node removed with queue_free() or free(). The variable does not become null by itself. Check it with is_instance_valid() before using it, or clear the variable when the node leaves.

Is a node invalid right after queue_free()?

No. queue_free() deletes the node at the end of the current frame, so until then is_instance_valid() is still true. Use is_queued_for_deletion() to know that a node is about to go.

Coddy programming languages illustration

Learn to code with Coddy

Get started