{"record":{"id":"28d7ff9312a53508","repo":"reflex-dev/reflex","slug":"cannot-directly-call-background-task-name-r-use","errorCode":null,"errorMessage":"Cannot directly call background task {name!r}, use `yield {type(state).__name__}.{name}` or `return {type(state).__name__}.{name}` instead.","messagePattern":"Cannot directly call background task (.+?), use `yield (.+?)\\.(.+?)` or `return (.+?)\\.(.+?)` instead\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"reflex/state.py","lineNumber":127,"sourceCode":"        state: The state instance the background task is bound to.\n        name: The name of the background task.\n        fn: The background task coroutine function / generator.\n\n    Returns:\n        A compatible coroutine function / generator that raises a runtime error.\n\n    Raises:\n        TypeError: If the background task is not async.\n    \"\"\"\n    call = f\"{type(state).__name__}.{name}\"\n    message = (\n        f\"Cannot directly call background task {name!r}, use \"\n        f\"`yield {call}` or `return {call}` instead.\"\n    )\n    if inspect.iscoroutinefunction(fn):\n\n        async def _no_chain_background_task_co(*args, **kwargs):  # noqa: RUF029\n            raise RuntimeError(message)\n\n        return _no_chain_background_task_co\n    if inspect.isasyncgenfunction(fn):\n\n        async def _no_chain_background_task_gen(*args, **kwargs):  # noqa: RUF029\n            yield\n            raise RuntimeError(message)\n\n        return _no_chain_background_task_gen\n\n    msg = f\"{fn} is marked as a background task, but is not async.\"\n    raise TypeError(msg)\n\n\ndef _substate_key(\n    token: str,\n    state_cls_or_name: BaseState | type[BaseState] | str | Sequence[str],\n) -> str:","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/reflex/state.py#L109-L145","documentation":"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.","triggerScenarios":"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).","commonSituations":"Refactoring a normal async event handler into a background task and forgetting to update call sites; new developers treating background tasks like regular methods.","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"],"exampleFix":"# before\nasync def do_work(self):\n    await self.my_bg_task()  # RuntimeError\n\n# after\n@rx.background\nasync def my_bg_task(self):\n    async with self:\n        ...\n\ndef do_work(self):\n    yield self.my_bg_task","handlingStrategy":"validation","validationCode":"import inspect\n\ndef is_background_task(fn) -> bool:\n    return getattr(fn, '_reflex_background', False) or fn.__name__.startswith('_no_chain_background_task')","typeGuard":"def is_background_task_handler(fn) -> bool:\n    return fn.__name__ in ('_no_chain_background_task_co', '_no_chain_background_task_gen')","tryCatchPattern":null,"preventionTips":["Never call @rx.background-decorated handlers directly; always yield/return them","Grep for 'await self.' calls that target background tasks when refactoring"],"tags":["reflex","background-tasks","event-handlers","state","runtime-error"],"backgroundTag":"invalid-background-task-invocation","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}