godot-cli
Godot CLI — Build Verification & Debug Output
Use this skill to run the Godot engine from the command line in headless mode to validate the project without opening the GUI editor. The godot binary must be installed and on PATH.
Quick Reference
| Goal | Command |
|---|---|
| Full import pass (catches missing resources, bad imports) | godot --headless --path . --import |
| Boot a scene, catch runtime errors, then exit | godot --headless --path . --scene <main_scene> --quit |
| Boot with verbose output (resource loading order, full leak details) | godot --headless --path . --scene <main_scene> --quit --verbose |
| Write output to a log file (duplicates stdout) | godot --headless --path . --scene <main_scene> --quit --log-file ./build_check.log |
| Parse a single script for errors (isolated — see caveat below) | godot --headless --path . --script path/to/script.gd --check-only |
| Open editor for interactive testing, capture debug output to log | godot --path . --log-file ./godot_debug.log |
| Run game directly for interactive testing, capture debug output to log | godot --path . --scene <main_scene> --log-file ./godot_debug.log |
All commands must be run from the project root or use --path to point there.
Standard Verification Workflow
After making code changes, run these two commands in order:
1. Import check
godot --headless --path . --import
This triggers the full resource import pipeline. It will report:
- Missing or corrupt resources
- GDExtension load failures
- Scene structure issues caught at import time
Clean output looks like this (ANSI progress bars followed by [ DONE ]):
Godot Engine v4.6.stable.official.89cea1439 - https://godotengine.org
[ 0% ] first_scan_filesystem | Started Project initialization (5 steps)
...
[ DONE ] first_scan_filesystem
[ DONE ] loading_editor_layout
2. Scene boot check
godot --headless --path . --scene <main_scene> --quit
This boots the main gameplay scene, runs one frame (autoloads initialize, _ready() fires on all nodes), then exits. It catches:
- GDScript compile errors (autoloads resolving, class references)
- Missing node path errors in
_ready() - Signal connection failures
- Runtime errors in initialization code
Known baseline warnings on a clean project (these are pre-existing and not bugs):
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
ERROR: 2 resources still in use at exit (run with --verbose for details).
These appear because --quit tears down the scene tree immediately. They are harmless in headless validation. Only flag new warnings/errors that appear beyond these two.
Exit code 0 = no fatal errors. Exit code 1 = a fatal error occurred (parse failure, missing scene, etc.).
Interactive Testing with Debug Log
When headless checks pass but you want to manually play-test and have debug output reviewed afterward, run Godot with --log-file from the project root. This opens the game normally while writing all engine output to a file that can be read after the session.
Open the editor (then press F5 to run)
godot --path . --log-file ./godot_debug.log
Run the game directly (skips the editor)
godot --path . --scene <main_scene> --log-file ./godot_debug.log
Play and test as normal. When you're done, close the game and the log file at the project root (godot_debug.log) contains the full debug output from the session — all errors, warnings, and print statements. Read it to review what happened during the test.
The log file path is relative to the project root. Clean it up afterward or leave it; it is not tracked by git (add to .gitignore if preferred).
Reading the Output
Error format
Godot errors follow this structure:
ERROR: <message>
at: <function> (<source>:<line>)
For GDScript errors specifically:
SCRIPT ERROR: <Parse Error | Compile Error>: <description>
at: GDScript::reload (<file path>:<line>)
ERROR: Failed to load script "<path>" with error "<reason>".
at: load (modules/gdscript/gdscript.cpp:<line>)
The SCRIPT ERROR line has the actionable info — file, line number, and what's wrong. The ERROR: Failed to load script line that follows is just the propagation.
Warning vs Error
WARNING:— non-fatal. The game continues. May or may not indicate a real problem.ERROR:— something failed. Usually fatal for the affected resource. Check exit code.
Verbose mode
If you need to see which resources are loading and in what order (useful for diagnosing dependency issues), add --verbose. This produces significantly more output. Pipe through tail or grep to focus:
# See only errors and warnings in verbose output
godot --headless --path . --scene <main_scene> --quit --verbose 2>&1 | grep -E "(ERROR|WARNING|SCRIPT)"
# See resource loading order
godot --headless --path . --scene <main_scene> --quit --verbose 2>&1 | grep "Loading resource"
Important Caveats
--check-only does NOT resolve autoloads
--script <file> --check-only parses the script in isolation. It cannot resolve references to autoload singletons or other project classes. This will always fail on scripts that use them:
SCRIPT ERROR: Compile Error: Identifier not found: MyAutoload
Use --check-only only for scripts that are fully self-contained (e.g., utility scripts with no project dependencies). For anything else, use the scene boot check instead.
--headless is required on CI / no-GPU environments
The --headless flag sets the display and audio drivers to dummy implementations. Without it, the command will try to open a window and may hang or crash in environments without a display.
--quit vs --quit-after
--quitexits after the first frame. Good for initialization checks.--quit-after <N>runs for N frames. Useful if you need to wait for async loading or deferred calls to execute. Example:--quit-after 10
Log file duplicates stdout
--log-file writes to the specified path in addition to stdout. The log file path is relative to the project directory. Clean up after use if not needed.
Godot Binary Location
Verify with:
which godot || where godot
godot --version