Quick answer: A GDScript stack trace appears in the Godot Output panel when an error occurs. It shows the error message first, followed by indented lines listing each function call in the chain. Each frame includes the script file path, the line number, and the function name.
This Godot stack trace debugging guide covers everything you need to know. Godot's error output tells you exactly what went wrong and where, but only if you understand how to read it. This guide walks through the structure of GDScript stack traces, the most common error patterns, how to use the built-in debugger to inspect live state, and how to debug games running on remote devices.
How Godot Reports Errors
When a GDScript error occurs, Godot prints a message to the Output panel and the Debugger tab. The format includes the error type, the script path, and the line number. A typical error looks like this:
ERROR: Invalid get index 'health' (on base: 'null instance').
at: GDScript::_process (res://scripts/enemy.gd:42)
at: GDScript::_on_hit (res://scripts/enemy.gd:78)
at: GDScript::_on_body_entered (res://scripts/player.gd:55)
The first line is the error message itself. It tells you the operation that failed and the type of the object it failed on. In this case, code tried to access a health property on a null instance. The following lines show the call stack, with the most recent call at the top.
Common GDScript Error Patterns
Null instance access. The most frequent error in Godot projects. It happens when you call a method or access a property on a variable that is null. Common causes include nodes that were freed with queue_free() but still referenced, get_node() calls with incorrect paths, and signals connected to objects that no longer exist.
func _on_hit(damage: float) -> void:
# This crashes if target was already freed
target.health -= damage
if target.health <= 0:
target.die()
The fix is to check is_instance_valid(target) before accessing any properties. In Godot 4, you can also use the ?. safe call operator to short-circuit on null references without crashing.
Type mismatch errors. GDScript is dynamically typed by default, so type errors surface at runtime rather than compile time. You see these as "Invalid type in function" errors. Using static typing (var health: float = 100.0) catches these earlier in the editor and produces clearer error messages when they do occur.
Signal connection failures. If you connect a signal to a method that does not exist, or the target node is freed before the signal fires, Godot reports an error with the signal name and the failed method. These often appear as "nonexistent function" errors and can be tricky because the connection was made at a different time than the error.
Using the Built-in Debugger
Godot includes a full debugger accessible from the bottom panel of the editor. When you run your game from the editor, you can set breakpoints by clicking the left margin next to any line number in the script editor. A red dot appears, and execution will pause when that line is reached.
When paused at a breakpoint, the Debugger tab shows the current stack trace, local variables, and member variables for the current object. You can step through code line by line with the Step Over and Step Into buttons. The Stack Variables panel lets you inspect the exact value of every variable at each frame in the call stack.
# Set a conditional breakpoint by adding this before the suspect line
if target == null:
breakpoint # Pauses execution here when target is null
The breakpoint keyword is a GDScript built-in that triggers a debugger pause without needing to use the editor UI. This is useful for conditional breakpoints where you only want to pause when a specific state is reached.
Remote Debugging on Devices
Bugs that only appear on exported builds or on specific hardware require remote debugging. Godot supports this through its remote debugger, which connects to a running game instance over TCP.
To enable remote debugging, go to your export preset and enable the Remote Debug option. When the exported game launches, it tries to connect back to the editor on the specified port. Once connected, you can set breakpoints, inspect variables, and view the stack trace as if the game were running locally in the editor.
For mobile and console builds where the editor cannot connect directly, you can use Godot's logging system to capture stack traces to a file. Set ProjectSettings.logging/file_logging/enable_file_logging to true, and Godot writes all errors and stack traces to user://logs/godot.log on the device.
GDExtension and Native Crashes
If your Godot project uses GDExtension modules written in C++ or Rust, crashes in native code will not produce GDScript stack traces. Instead, you get a platform-specific crash dump with native addresses. On Linux, the crash manifests as a SIGSEGV signal. On Windows, you get an access violation and a minidump.
For these native crashes, you need to build your GDExtension with debug symbols and use platform tools like GDB or WinDbg to analyze the crash dump. Godot's print_error and push_error functions can help you log context before the native crash occurs, giving you breadcrumbs to follow.
"The best stack trace is one your players never have to see. But when they do, make sure it lands in your bug tracker, not in a Discord message you miss."
Automating Error Collection in Godot
Godot does not include a built-in crash reporting system for shipped games. To collect errors from players automatically, you need an SDK that hooks into the error reporting pipeline. Bugnet's Godot SDK registers a custom error handler that captures every GDScript error along with its stack trace, packages it with device metadata, and uploads it to your Bugnet dashboard. Crashes are grouped by their stack trace signature, so you can see how many players are affected and prioritize fixes based on impact.
Related Issues
For a general introduction to stack traces in game development, see our beginner's guide to reading game stack traces. To integrate bug reporting into your Godot project, check out how to add a bug reporter to a Godot game. If you are just starting with Godot, our getting started with Godot guide covers the fundamentals.
Use is_instance_valid() before accessing any node reference that might have been freed. Your future self will thank you.