Fixing null instance errors with nodes in Godot 4

2026/04/02

Type
Learning Resource
Format
Study Guide
Version
Godot 4.x
Subject Tags
  • Update/Code Patch
Code
MIT
Game Assets
2016-2026, GDQuest© - All rights reserved
All else
2016-2026, GDQuest© - All rights reserved
Created
2025/08/13
Updated
2026/04/02

Fixing null instance errors with nodes in Godot 4

If you worked with Godot for a bit, you've probably seen this error (or something similar): Invalid assignment of property or key 'position' with value of type 'Vector2' on a base object of type 'null instance'.

It's one of the most common errors beginners encounter in Godot, and the good news is it's usually quick to fix once you know what to look for.

This error happens when your code tries to access member variables or functions on a node that doesn't exist or can't be found. Godot can't run the code you ask because there's nothing to act on.

This is what the error looks like in practice:
The null instance error appearing in Godot's debugger

If Godot can't find a node you're trying to get with get_node(), it returns null instead of the node. When you try accessing member variables or calling functions on that value, as if it were a real node, the engine stops and shows you the "null instance error."

In this study guide, you'll find:

Understanding what triggers the error

Let me show you exactly what the error looks like in practice. Here's a simple scene with a player character to help me demonstrate this issue.

In this Player scene there is a child Area2D node I've renamed "HurtBox" that I need to access in the script:

Scene dock showing a Main node with a Player child node

Here's the script I have attached to the Player node:

extends CharacterBody2D

var health := 5

@onready var hurt_box: Area2D = $Hurtox


func _ready() -> void:
	hurt_box.area_entered.connect(
		func(area_that_entered: Area2D) -> void:
			health -= 1
	)

See that typo? I wrote $Hurtox but in the Scene dock, the node is named "HurtBox". It's just one missing letter, but it's enough to break everything.

When Godot runs this code, here's what happens:

  1. Godot calls the get_node() function ($ is a shorthand for get_node() in Godot) and tries to find a node named exactly "Hurtox".
  2. Since there's no node with that exact name, the get_node() function returns null. Most programming languages have a special null value or object. It represents a missing value, a reference to nothing (we call that a "null reference").
  3. The hurt_box variable now points to null instead of a reference to the actual "HurtBox" node.
  4. When we reach the line hurt_box.area_entered.connect(), it's as if we're really trying to access null.area_entered.connect().
  5. Godot throws the error because null doesn't have any member variables, functions, or signals, so it doesn't have an area_entered signal and that's an error.

When you get a node in code, you have to pass the exact name or path to the node when calling the get_node() function.

The name you passed to the get_node() function has to match exactly the names in your Scene dock or Godot will not find the nodes.

In this case, it has to be exactly "HurtBox" and not "hurtbox" or "Area2D" or "Hurtbox" or anything else. Capital and lowercase letters have to match exactly.

Nathan

Founder and teacher at GDQuest

This is just one way this error can happen, but that's what the error is about. In the next section, I'll walk you through the most common causes and how to fix each one.

Troubleshooting checklist

When Godot stops the project because of a null instance error, you can use this checklist to find and fix the issue. I've ordered these from the most common to the least common causes.

There are 5 common causes of this error:

Having a typo in the node name

The problem: You typed the node name incorrectly when trying to access it. This is by far the most common cause.

Side by side comparison showing $Playe in code vs Player in Scene dock

Why this happens: Node names are case-sensitive and must match exactly. Even player vs Player will cause this error.

How to fix:

The safest way to avoid typos is to let Godot write the node path for you. Here are a few options to do this.

When you start typing the $ symbol followed by a few letters, Godot should show you a list of matching node names from the Scene dock. You can select the correct one from the dropdown to avoid typos.

NOTE:
If you're not seeing autocomplete suggestions, make sure code completion is enabled by checking the Editor SettingsGeneralText EditorCompletionCode Complete Enabled setting.
Code completion dropdown showing node name suggestions

Another option is to copy the node path directly from the Scene dock. This is especially useful if you have a long path to the node (like $Enemies/Enemy/HurtBox) that would be easy to mistype. Right-click the node in the Scene dock and select "Copy Node Path" to get the exact path to paste into your script:

Copy node path from the node's right-click menu in the Scene dock

Yet another option is to hold down Ctrl while clicking and dragging the node from the Scene dock directly into your script:

This automatically creates an @onready variable with the correct path. You can't make typos then!

Using the node type instead of the node name

The problem: You're trying to get a node by its class type (like "Timer" or "Area2D") instead of its actual name in the scene.

Why this happens: When you add a node to a scene, Godot gives it a default name based on its type ("Timer", "Area2D", etc.). But you often rename these nodes to be more descriptive. The get_node() function searches by the name you see in the Scene dock, not by the node type.

How to spot it: Check if your code uses generic type names like this:

@onready var timer = $Timer
@onready var area = $Area2D

Godot is searching for a node named exactly "Timer" for the timer variable, and exactly "Area2D" for the area variable. It's not looking for any node of type Timer or Area2D. But in your Scene dock, those nodes might have specific names like "CooldownTimer" or "HurtBox":

Scene dock showing a Timer node renamed to CooldownTimer

How to fix:

Use the actual name from the Scene dock. If the timer node is named "CooldownTimer" in the scene, your code needs to be:

@onready var timer = $CooldownTimer
Writing an incorrect node path (the node is not a direct child)

The problem: You're using $NodeName syntax, but it turns out NodeName isn't a direct child of the node having the script you're currently editing.

Why this happens: When you pass a simple node name to the $ symbol (like $Enemy), Godot considers only direct children of the node with the script attached. If the node is nested deeper in the scene tree, you need to type the complete path through all parent nodes.

How to spot it: Look at your Scene dock structure. If there are other nodes between your script's node and the target node, you need the full path.

Scene dock showing Enemy node nested inside an Enemies parent node

In this example, if you're editing the script attached to the Main node and you write:

@onready var enemy = $Enemy

Godot looks for a direct child named "Enemy", but can't find it because "Enemy" is actually a child of "Enemies".

How to fix:

Use the full path to reach nested nodes:

@onready var enemy = $Enemies/Enemy
Using % when a node does not have a scene unique name

The problem: You're using the % syntax to get a node, but you haven't marked that node as having a scene unique name.

Why this happens: The % syntax is a special feature that lets you access nodes from anywhere in a scene, regardless of their position in the tree. But it only works for nodes you've explicitly marked with a scene unique name. Without turning on this option on the node, Godot doesn't know to make the node available through the % syntax.

How to spot it: Your code uses % like this:

@onready var health_bar = %HealthBar

But you get a null instance error even though a node named "HealthBar" exists in your scene.

How to fix:

Right-click the node in the Scene dock and select "Access as Scene Unique Name":

Right-click menu showing the Access as Scene Unique Name option

After setting it, you'll see a % icon next to the node name:

Scene dock showing a node with the % icon indicating it has a scene unique name

Now your %HealthBar reference will work from anywhere in the scene.

NOTE:
Unique names are scoped and only work within one scene. You cannot access a node using a unique name with % from outside this scene instance. In other words, you couldn't access this "HealthBar" node from outside the Player scene by calling get_node("%HealthBar") or equivalent.
Renaming a node without updating the code

The problem: You renamed a node in the Scene dock but forgot to update your script references.

Why this happens: Godot doesn't automatically update your code when you rename nodes in the Scene dock. The connection between your script and the scene is just through text, so changing the node name breaks all existing references until you update them manually.

How to spot it: You recently renamed a node to make it clearer (like changing "Marker2D" to "PlayerSpawner"), but now you're getting the null instance error.

How to fix:

After renaming any node, search for all references in your code:

  1. Press Ctrl+Shift+F (or Cmd+Shift+F on macOS) to open the "Find in Files" dialog.
  2. Search for the old node name.
  3. Update each reference to use the new name.

First, I search for "Marker2D" in the Find in Files dialog to find all the places I need to update after renaming the node to "PlayerSpawner".

Using the Find in Files dialog to search for an old name to replace

I make sure to click the Replace... button, so I get the option of replacing the text from the results panel.

Results panel after searching for Marker2D in Find in Files

See how I toggled off replacing some of the results? That's because I used types in my code, like var player_spawner: Marker2D. We don't want to replace those, otherwise we'd break the code.

An issue with this method is that you have to uncheck all the irrelevant results manually if you're using types in your code. And, as you can see from the Replace all (no undo) button... there's no undo for this operation. Yikes! If you have a large code base this brings more problems than it solves. You're better off organizing your scenes upfront, as you make them.

Questions and troubleshooting

What is @onready and how is it used?

When you create a variable that references a node, you need to wait for the scene tree to be ready before accessing it. The @onready annotation tells Godot to wait until the node and its children are added to the scene tree and finished running their _ready() function before getting the node reference.

Without @onready, your code runs before the scene tree is ready, and the node isn't exposed yet, which leads to the variable pointing to null:

extends Node2D

var player = $Player

The line var player = $Player runs immediately when the script is loaded, before other nodes have been created and added to the game's scene tree, and player will be assigned null. This leads to the null instance error when you try to use player later in the code.

Adding @onready fixes this by telling Godot to wait:

extends Node2D

@onready var player = $Player

This is a shortcut that's equivalent to writing:

extends Node2D

var player  = null

func _ready() -> void:
	player = $Player

If you're getting a null instance error and none of the checklist items above apply, check that all your node references use @onready or that you are getting nodes in the _ready() function.

updates / code patches

Become an Indie Gamedev with GDQuest!

Don't stop here. Step-by-step tutorials are fun but they only take you so far.

Try one of our proven study programs to become an independent Gamedev truly capable of realizing the games you’ve always wanted to make.

Nathan

Founder and teacher at GDQuest
  • Starter Kit
  • Learn Gamedev from Zero
Check out GDSchool

You're welcome in our little community

Get help from peers and pros on GDQuest's Discord server!

20,000 membersJoin Server

Contribute to GDQuest's Free Library

There are multiple ways you can join our effort to create free and open source gamedev resources that are accessible to everyone!

Site in BETA!found a bug?