Skip to content

Why do I get "Nonexistent function"?

Godot 4.x

You’ll see something like one of these in the Debugger panel. The function and node names will be your own:

_on_body_entered(): Invalid call. Nonexistent function 'take_damage' in base 'TileMapLayer'.
spawn(): Invalid call. Nonexistent function 'set_target' in base 'PackedScene'.
What’s happeningGo to
The base is a node you didn’t expect, like TileMapLayer or StaticBody2DThe wrong node got the call
The base is PackedSceneCalling the scene instead of the instance
The base is your node and the function is right there in the scriptThe script isn’t on that node
Everything looks rightA typo

The player has a take_damage() function. The enemy is an Area2D that calls it on whatever enters.

  • MainNode2D
    • PlayerCharacterBody2Dhas scripthas take_damage()
    • EnemyArea2Dhas scriptcalls take_damage()
    • WallsTileMapLayer

The variable holds a different node than you think. Here, body is whatever touched the enemy. Most of the time that’s the player, but when the enemy touches the walls, body is the TileMapLayer, and a TileMapLayer has no take_damage():

enemy.gd
extends Area2D
func _on_body_entered(body: Node2D) -> void:
body.take_damage(10)

Fix: check before you call.

enemy.gd
func _on_body_entered(body: Node2D) -> void:
body.take_damage(10)
if body.has_method("take_damage"):
body.take_damage(10)

get_parent() causes the same surprise. It returns whatever the parent is right now, so moving a script to a different node silently changes what get_parent() points at.

A PackedScene is the blueprint. It has no take_damage() and no position. You need to instantiate() it first, then call things on the result:

spawner.gd
const ENEMY := preload("res://enemy.tscn")
func spawn() -> void:
ENEMY.set_target(player)
var enemy := ENEMY.instantiate()
enemy.set_target(player)
add_child(enemy)

The function is in player.gd, but player.gd has to be attached to the node you’re calling. Select the node in the Scene dock and look at the script icon on the right of its name. If it’s missing, or shows a different file, that’s the problem. It often happens after duplicating a scene or dragging a script onto the wrong node.

If the node is an instance of another scene (player.tscn), the script lives in that scene. Open it and check there.

Function names are case-sensitive and exact: take_damage, takeDamage and take_dmg are three different functions. Copy the name from the definition rather than retyping it. The script editor underlines calls it can’t resolve on nodes with a known type, so give your variables types where you can:

var player = $Player
var player: Player = $Player

The error names the base node’s class, not its name. If it says in base 'Node2D', work out which Node2D that is: put print(body.name) or print(body.get_path()) on the line above the call and run again. Once you know which node it is, the fix is usually obvious.