reflex-dev/reflex · error · RuntimeError
Cannot directly call background task {name!r}, use `yield {t
Error message
Cannot directly call background task {name!r}, use `yield {type(state).__name__}.{name}` or `return {type(state).__name__}.{name}` instead. What it means
Reflex background tasks (@rx.background) cannot be chained by calling them directly like normal event handlers, because they run in a separate task with their own state snapshot. Calling such a coroutine raises RuntimeError with a message telling you to yield or return the handler reference instead. The wrapper _no_chain_background_task_co replaces the original async function.
Source
Thrown at reflex/state.py:127
state: The state instance the background task is bound to.
name: The name of the background task.
fn: The background task coroutine function / generator.
Returns:
A compatible coroutine function / generator that raises a runtime error.
Raises:
TypeError: If the background task is not async.
"""
call = f"{type(state).__name__}.{name}"
message = (
f"Cannot directly call background task {name!r}, use "
f"`yield {call}` or `return {call}` instead."
)
if inspect.iscoroutinefunction(fn):
async def _no_chain_background_task_co(*args, **kwargs): # noqa: RUF029
raise RuntimeError(message)
return _no_chain_background_task_co
if inspect.isasyncgenfunction(fn):
async def _no_chain_background_task_gen(*args, **kwargs): # noqa: RUF029
yield
raise RuntimeError(message)
return _no_chain_background_task_gen
msg = f"{fn} is marked as a background task, but is not async."
raise TypeError(msg)
def _substate_key(
token: str,
state_cls_or_name: BaseState | type[BaseState] | str | Sequence[str],
) -> str:View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Replace the direct call with `yield self.my_bg_task` (in a generator handler) or `return self.my_bg_task` (in a regular handler)
- Ensure the calling event handler yields/returns the background handler so Reflex schedules it correctly
- Pass any arguments via the yielded handler: `yield self.my_bg_task(arg1)` only if the API supports it — otherwise store args in state first
Example fix
# before
async def do_work(self):
await self.my_bg_task() # RuntimeError
# after
@rx.background
async def my_bg_task(self):
async with self:
...
def do_work(self):
yield self.my_bg_task Defensive patterns
Strategy: validation
Validate before calling
import inspect
def is_background_task(fn) -> bool:
return getattr(fn, '_reflex_background', False) or fn.__name__.startswith('_no_chain_background_task') Type guard
def is_background_task_handler(fn) -> bool:
return fn.__name__ in ('_no_chain_background_task_co', '_no_chain_background_task_gen') Prevention
- Never call @rx.background-decorated handlers directly; always yield/return them
- Grep for 'await self.' calls that target background tasks when refactoring
When it happens
Trigger: Inside an event handler, calling `self.my_bg_task()` directly where my_bg_task is decorated with @rx.background and defined as an async def (coroutine).
Common situations: Refactoring a normal async event handler into a background task and forgetting to update call sites; new developers treating background tasks like regular methods.
Related errors
- To access rx.State in frontend components, at least one subc
- ChildrenTypeError(component=cls.__name__, child=child)
- Do not override _add_style directly. Use add_style instead.
- The component `{comp_name}` only allows the components: {val
- Undefined library for NoSSRComponent
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/28d7ff9312a53508.
Report an issue: GitHub.