Skip to content

bug: Tasks created by Page.run_task can not be awaited #6515

Open

Description

@jnsh

Duplicate Check

Describe the bug

The Page.create_task returns a Future object of concurrent.futures.Future type. This type of Future object is not awaitble.

As awaiting is often essential with asynchronous applications, it would be nice if the run_task could return an awaitable type, such as asyncio.Future or asyncio.Task.

It is possible to use Page.loop.create_future() or Page.loop.create_task() to get awaitable Task or Future objects, but somehow those do not seem to integrate with Flet event loop as well as Page.create_task, as sometimes the UI does not update as expected.

Code sample

Code
import flet as ft


async def main(page: ft.Page):

    async def coro():
        pass

    # works
    loop_create_task = page.loop.create_task(coro())
    print("awaiting page.loop.create_task, type:", type(loop_create_task))
    await loop_create_task
    print("awaited successfully\n")

    # works
    loop_create_future = page.loop.create_future()
    print("awaiting page.loop.create_future, type:", type(loop_create_future))
    loop_create_future.set_result(None)
    await loop_create_future
    print("awaited successfully\n")

    # fails
    page_run_task = page.run_task(coro)
    print("awaiting page.run_task, type:", type(page_run_task))
    await page_run_task
    print("awaited successfully\n")


ft.run(main)

To reproduce

  1. Create task with Page.run_task
  2. Try to await the returned Future

Expected behavior

No response

Screenshots / Videos

No response

Operating System

Linux

Operating system details

Arch Linux

Flet version

0.85.1

Regression

I'm not sure / I don't know

Suggestions

No response

Logs

Additional details

No response

Activity

  1. added
    bugSomething isn't working
    on May 21, 2026
  2. ihmily commented on May 25, 2026

    @ihmily
    Contributor

    It seems this is expected behavior with the current page.run_task() implementation, rather than a bug in await itself.

    page.run_task() is primarily designed to submit a coroutine to the page's event loop as a background task—especially from synchronous callbacks or lifecycle hooks. Internally, it uses asyncio.run_coroutine_threadsafe(...) , which returns a concurrent.futures.Future by design. As a result, the returned object is not directly awaitable.

    Therefore, run_task() should be treated as a scheduling API, not as the async equivalent of asyncio.create_task().

    In native async code, the preferred patterns are:
    await coro()
    await page.loop.create_task(coro())

    If you just want to run a task without waiting for it, you can simply call page.run_task(). However, if you do need to await the result, you must wrap the future as shown below:

    import flet as ft
    import asyncio
    
    async def main(page: ft.Page):
        async def coro():
            print("running coroutine")
    
        # Get the concurrent.futures.Future returned by page.run_task
        concurrent_future = page.run_task(coro)
    
        # Wrap it into an asyncio.Future using asyncio.wrap_future, then await it
        asyncio_future = asyncio.wrap_future(concurrent_future)
    
        await asyncio_future
        print("awaited successfully\n")
    
    ft.run(main)
    
  3. self-assigned this
    on Oct 27, 2026
  4. moved this from 🆕 New to 👀 In review in Flet Developmenton Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions