Chris Marriott
08/20/2026, 10:40 AMMarvin
08/20/2026, 10:40 AMMarvin
08/20/2026, 10:41 AMVariable.get() can be called from ordinary Python code outside a flow or task:
from prefect.variables import Variable
value = Variable.get("my_variable") # synchronous code
In async code:
value = await Variable.get("my_variable")
It uses the configured Prefect API/profile; a flow or task context is not required.Chris Marriott
08/20/2026, 10:44 AMMarvin
08/20/2026, 10:44 AMMarvin
08/20/2026, 10:48 AMprefect deploy imports your flow module while its own async event loop is running. In Prefect 2.20, Variable.get() and Block.load() are “sync-compatible”; when they detect that async context, they return coroutines—even if your flow itself is synchronous.
Also, Variable.get() returns the stored value directly, so it should not have .value.
Recommended: avoid loading Variables or Blocks at module import time. Load them inside the synchronous flow/task:
from prefect import flow
from prefect.variables import Variable
from prefect.blocks.system import Secret
@flow
def my_flow():
env = Variable.get("env")
secret = Secret.load("my-secret").get()
If they absolutely must be module-level, force Prefect 2.20's synchronous path:
ENV = Variable.get("env", _sync=True)
BLOCK = MyBlock.load("my-block", _sync=True)
_sync=True is an internal compatibility argument, so moving the calls into the flow is more robust. This exact module-import behavior is tracked in Prefect issue #15086.