Attempt to call function 'add_child' in base 'null instance' on a null instance

Godot Version

Godot 4.4

Question

when i ty to run my main scene, it keeps saying “Attempt to call function ‘add_child’ in base ‘null instance’ on a null instance”, but i dont know what its talking about. Heres the code:

extends Node2D

@onready var pause_menu = %PauseMenu
@onready var sub_viewport = $SubViewportContainer/SubViewport
@onready var sub_viewport_container = $SubViewportContainer
var recentWindowSize = Vector2i()
var paused : bool = false
@export var levels : Dictionary[String, String] = {
“hidden”: “res://Scenes/levels/hidden_level.tscn”
}
@onready var transition = $CircleTransition
@onready var start_delay = $StartDelay
@onready var pre_transition = $PreTrans

func _ready():
Global.viewport = $SubViewportContainer
loadLevel(Global.selectedLevel)
start_delay.start()

func _process(delta):

## F11 keybind thingy ##
if Input.is_action_just_pressed("f11"):
	if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_FULLSCREEN:
		DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
	elif DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_WINDOWED:
		DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)

if Input.is_action_just_pressed("pause"):
	pauseMenu()

func pauseMenu():
if paused:
pause_menu.hide()
get_tree().paused = false
else:
pause_menu.show()
get_tree().paused = true

paused = !paused

func loadLevel(level : String):
var selected = levels[level]
var levelScene = load(selected).instantiate()
print(levelScene)
print(levels[level])
sub_viewport.add_child(levelScene)

func transitionStart():
pre_transition.hide()
transition.transition_out()

func _on_start_delay_timeout():
transitionStart()

It is probably this line:
sub_viewport.add_child(levelScene)

And the error message is telling you that you are trying to add a child to a null instance. So your sub_viewport is not valid, ie it is null.

You seem to be calling add_child in your load_level function, which is called from your ready function.

You can test if its valid like this:

if is_instance_valid(sub_viewport):  
    sub_viewport.add_child(levelScene) 

but you should really find out why, when you expected it to be valid, it is not. Perhaps you used the wrong name? Perhaps the path to it is wrong? It could be a multitude of reasons TBH.

You might just need to defer the call to the next frame to wait for the sub_viewport to be ready itself.

sub_viewport.call_deferred("add_child", levelScene)  

Try printing it to see if it is valid in the ready function:

func _ready():
      print(sub_viewport.name)

Good luck with your game.