Trying to call an async function without "await" in Godot 4
By Eduardo Orellana · Updated
The called function contains await, so it is a coroutine, and its return value was used without await in front of the call. Put await before the call, var count = await loader.load_level(), so the line waits for the function to finish and gets its real return value.
What Godot is checking
A function that contains await is a coroutine. When it reaches its first await it returns to the caller straight away, and what it returns at that point is a GDScriptFunctionState object, not the value from its return statement.
When a call's return value is used, the VM looks at what came back. If it is a GDScriptFunctionState and the call was not compiled as an awaited call, it stops with Trying to call an async function without "await". The check is inside DEBUG_ENABLED, so it runs in the editor and debug builds.
It is a runtime error: the script parsed, and the error appeared when the line ran. The function that made the call stops there, so the print("after") below it never ran, as the output shows.
The analyzer has its own check. When it knows which function is called and that it is a coroutine, a call used as a value stops the script at parse time with Function "load_level()" is a coroutine, so it must be called with "await". A call on its own line gets the MISSING_AWAIT warning instead. In the repro the call goes through an untyped variable, var loader = get_node("."), so the analyzer does not know the function, and the run shows it parsed and failed only when it ran.
Reproduce it
A load_level() function that waits one frame and returns a number, called through an untyped variable with its return value stored and no await.
extends Node
func load_level() -> int:
await get_tree().process_frame
return 3
func _ready() -> void:
var loader = get_node(".")
var count = loader.load_level()
print("after ", count)
What Godot 4.7.2 prints
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org
SCRIPT ERROR: Trying to call an async function without "await".
at: _ready (res://answers/trying-to-call-an-async-function-without-await/repro.gd:9)
GDScript backtrace (most recent call first):
[0] _ready (res://answers/trying-to-call-an-async-function-without-await/repro.gd:9)Fix it
Put await before the call. The line waits until load_level() returns, and count gets its return value.
extends Node
func load_level() -> int:
await get_tree().process_frame
return 3
func _ready() -> void:
var loader = get_node(".")
var count = await loader.load_level()
print("level count ", count)
What the fixed script prints
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org
level count 3Verified on Godot 4.7.2
Both scripts on this page were run headless on Godot 4.7.2 (4.7.2.stable.mono.official.ed1daf0bf) on 6 October 2026, and the output above is what Godot printed, unedited.
Where the check lives in Godot's source: [gdscript_vm.cpp lines 1958 to 1966, the check and the message](https://github.com/godotengine/godot/blob/4.7.2-stable/modules/gdscript/gdscript_vm.cpp#L1958-L1966), [gdscript_analyzer.cpp lines 3776 to 3784, the parse-time check and the MISSING_AWAIT warning](https://github.com/godotengine/godot/blob/4.7.2-stable/modules/gdscript/gdscript_analyzer.cpp#L3776-L3784).
Questions
- Why didn't the editor flag the call?
- The analyzer checks for a missing await only when it knows the called function is a coroutine. Through an untyped variable it does not, so the call is checked when it runs, as in the repro.
- Does the caller become a coroutine too?
- Yes. A function that contains await is a coroutine, so once _ready() awaits load_level(), _ready() also returns to its own caller at that line and finishes later.
Related
- How to wait in Godot 4: "yield" was removed, use await
- Invalid call to function '…' in base '…'. Expected N argument(s)
- Every verified Godot 4 answer
- Trying to assign a non-object value to a variable of type '…' in Godot 4
- Invalid type in static function '…' in type '…'. Cannot convert argument in Godot 4
- The "tool" keyword was removed in Godot 4: use @tool
- Invalid access to property or key on a base object of type 'null instance' in Godot 4
- Invalid assignment of property or key with value of type on a base object of type 'Nil' in Godot 4
Flockbay's agent reads Godot's debugger output and fixes errors like this one in your project, on the official Godot.
Download Flockbay free