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
1 Like

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”

1 Like

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!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.