Invalid call when attempting to append data to an Array

Godot Version

v4.3.stable.steam

Question

When attempting to append data to the Array _items [using _items.append(myData)], I get the error message Invalid call. Nonexistent function 'append' in base 'Nil'.

I am confident that _items is an array, given that the Stack Trace/Filter Stack Variables/Members lists _items as an Array with size 0, as seen here:

Image

For reference, I am following this tutorial (written for godot v3, with me updating to v4 as needed) for making an inventory & item system.

Can you paste your code?

Here’s a cut-down version of the code that results in the error:

@export var _items = Array():
	get:
		get_items
	set(items):
		set_items

func set_items(newItems):
	if newItems:
		_items = newItems
	emit_signal("inventory_changed", self)

func get_items():
	return _items

func get_item(index: int):
	return _items[index]

func add_item(itemName: String, quantity: int = 1):
	var item = ItemDatabase.get_item(itemName)
	_items.append(item) ## This is where the error occurs
	emit_signal("inventory_changed", self)

That seems like your setter even refuses to set _items null. Is there any chance this script is called before it’s ready? I notice the stack trace mentions it’s called from initializePlayer, maybe that’s contributing?

I don’t think so. add_item() is being called from this fuction:

func initializePlayer():
	player = get_tree().root.get_node("/root/Main/Player")
	if not player:
		return
	
	emit_signal("player_initialized")
	
	player.inventory.connect("inventory_changed", Callable(self, "_on_player_inventory_changed"))
	
	var existingInventory = load("user://inventory.tres")
	if existingInventory:
		player.inventory.set_items(existingInventory.get_items())
	else:
		#Let's give the player a Dagger
		player.inventory.add_item("Dagger") # This is where add_item() is being called from
get:
		get_items

It is the callable here that is causing you grief
Switch it to

get:
	return _items

This might be a bug. At the very least a quirk of callable handling.
If you give the variable a type it will report “not all code paths return a value”.

@export var _items:Array = Array():
	get:
		get_items

func get_items()->Array:
	return _items

Ah yeah @sancho2 is onto something, you are using setters/getters wrong.

For starters you do not need the getter in your case, to set the get/set to a specific function you use equals, try this.

@export var _items = Array(): set = set_items

Right now you are making a get function that returns nothing, and making a set function that calls nothing. Maybe your warnings point out “this line has no effect”

Update: After saving and reloading the project, it started working again. I have no idea why this is, but I’ll take it.

Final update: The above was actually due to a hidden technical detail specific to my implementation of an unrelated process, and I have successfully fixed the issue with this solution. Thank you both for your help!