Quick answer: This error occurs when the Callable you pass to connect() references a method name that does not exist on the target object. In Godot 4, using the old string-based syntax Callable(self, 'method_name') requires exact spelling. Switch to the direct callable syntax signal.

Here is how to fix nonexistent function connecting signals Godot. You try to connect a signal in Godot 4 and the engine throws a “Nonexistent function” error at runtime. The method is right there in your script. You can see it. Yet Godot insists it does not exist. This error almost always comes down to a mismatch between how you reference the method and where the method actually lives.

The Symptom

When your scene loads or when the connection code runs, the Output panel shows an error like:

Error: Nonexistent function '_on_enemy_died' in base 'Node2D'.
  at: connect (core/object.cpp:1234)

Your code might look like this:

extends Node2D

func _ready():
  var enemy = $Enemy
  enemy.connect("died", Callable(self, "_on_enemy_died"))

func _on_enemy_died():
  print("Enemy defeated!")

The method _on_enemy_died is clearly defined on the same script. The error makes no sense at first glance. But the problem is often more subtle than a missing method — it is about how Godot resolves the Callable reference.

What Causes This

Cause 1: Using the Godot 3 string-based connection syntax in Godot 4. In Godot 3, the connect() method took three arguments: connect("signal", target, "method"). In Godot 4, this syntax was replaced with Callables. If you write connect("signal", Callable(target, "method")), the string method name is resolved at runtime, and any mismatch — including case sensitivity, underscores, or the method being on a different node than you think — causes this error.

Cause 2: The method exists on a different object than the one you passed. When you write Callable(self, "_on_enemy_died"), you are telling Godot to look for that method on self. If self is a Node2D with no script, or the script was recently changed and the editor has not refreshed, the method resolution fails. This also happens when you accidentally pass a parent or child node instead of the node that actually has the method.

Cause 3: The method is private or defined in a tool script context. While GDScript does not have true access modifiers, methods prefixed with underscore are treated differently in some internal resolution paths. If your method name has unusual characters or is defined inside an inner class, the StringName resolution may fail.

The Fix

Step 1: Use the direct Callable syntax. This is the single most effective fix. Instead of passing a string, pass a direct method reference:

# Old Godot 3 style — error-prone in Godot 4
enemy.connect("died", Callable(self, "_on_enemy_died"))

# Correct Godot 4 style — compile-time checked
enemy.died.connect(_on_enemy_died)

With the direct syntax, the GDScript parser validates the method reference when the script is loaded. If the method does not exist, you see the error in the editor before you even run the game.

Step 2: Verify the target object has the correct script. If you must use string-based Callables (for example, when connecting to dynamically loaded objects), verify the method exists before connecting:

func _ready():
  var target = get_node("/root/Game/HUD")

  # Check that the method exists before connecting
  if target.has_method("_on_score_changed"):
    score_changed.connect(Callable(target, "_on_score_changed"))
  else:
    push_warning("Target node missing _on_score_changed method")

Step 3: Update migrated Godot 3 code systematically. If you migrated a project from Godot 3, search your codebase for the old connection pattern and replace every instance:

# Find all old-style connections and update them

# Before (Godot 3):
button.connect("pressed", self, "_on_button_pressed")

# After (Godot 4):
button.pressed.connect(_on_button_pressed)

# Before (Godot 3 with binds):
button.connect("pressed", self, "_on_button_pressed", [item_id])

# After (Godot 4 with bind):
button.pressed.connect(_on_button_pressed.bind(item_id))

Why This Works

The direct Callable syntax works because GDScript resolves the method reference at parse time rather than at runtime. When you write _on_enemy_died as a bare identifier, the parser looks it up in the current script’s symbol table immediately. If it does not exist, the script fails to parse and the error appears in the editor with a line number and red underline. This moves the error from an unpredictable runtime failure to a predictable compile-time check.

The has_method() guard works for dynamic cases because it queries the object’s actual method list at runtime before attempting the connection. This prevents the error entirely by converting it into a handled condition that you can log or respond to gracefully.

Updating migrated Godot 3 code fixes the root cause for projects that were converted using the automatic migration tool. The migrator does its best to convert connection syntax, but it cannot always determine the correct Callable form, especially when the target or method comes from a variable rather than a literal string.

“Every Godot 3 to 4 migration generates at least a dozen Nonexistent Function errors from signal connections. Update them all at once and save yourself the whack-a-mole.”

Related Issues

If your signal connects without error but the callback never fires, that is a different problem related to node tree status or deferred connections. See our guide on fixing signals that are connected but whose callbacks never execute.

If you are getting errors about signal arguments not matching the method signature, the connection itself works but the parameter count is wrong. Check our post on fixing signal argument mismatches.

For custom signals that do not appear in the editor at all, the issue is with signal declaration syntax. See fixing custom signals not showing in the editor.

String-based Callables are a Godot 3 habit. Break it.