Duplicate Check
Describe the bug
In Flet 0.81.0 web mode (server-side, Docker), all Service controls (FilePicker, UrlLauncher) fail to work. page.launch_url() is also deprecated and delegates to UrlLauncher internally. There is no working way to open a native file dialog or launch a URL from a Flet web app in 0.81.0.
Two distinct failure modes depending on how/when the control is registered:
Mode A — "Unknown control: FilePicker" (red error bar across all views)
Occurs when FilePicker is added to page.overlay before or during the first page.update() — e.g., in main(), MainLayout, or app.py. The JS client doesn't recognize the control because the control tree handshake hasn't completed yet.
Mode B — TimeoutException after 10s: Timeout waiting for invoke method listener
Occurs when FilePicker is created per-click (inside the button handler), added to page.overlay, page.update() called, then await picker.pick_files() called. The JS listener for FilePicker never registers in time.
Environment
Python: 3.12.13 (CPython, Linux/Docker WSL2)
Flet: 0.81.0
Platform: Web mode (flet.app with server-side rendering, accessed via browser)
Docker: containerized app
OS host: Windows 11 + WSL2
Reproduction (minimal)
import flet as ft
async def main(page: ft.Page):
async def pick_file(_):
picker = ft.FilePicker()
page.overlay.append(picker)
page.update()
# Fails with TimeoutException after 10s in web mode:
result = await picker.pick_files(with_data=True)
print(result)
page.add(ft.ElevatedButton("Pick file", on_click=pick_file))
ft.app(main, port=8550)
All registration strategies attempted (all fail in web mode)
| Strategy |
Result |
FilePicker global in shared state |
Breaks multi-session (shared across users) |
FilePicker in MainLayout.did_mount() |
"Unknown control" on every view |
FilePicker per-click with overlay.append() + update() |
TimeoutException after 10s |
FilePicker in main() before first navigate() |
"Unknown control" on login view |
Per-click with asyncio.sleep(0.3) before pick_files() |
TimeoutException — sleep not enough |
ft.UrlLauncher().launch_url(url) |
Same problem — Service needs page registration |
page.launch_url(url) |
Deprecated, delegates to UrlLauncher internally |
Diagnostic output (check_flet.py --compat)
FilePicker
[OK] ft.FilePicker exists
[OK] pick_files() is ASYNC
[OK] with_data=True available
[OK] FilePicker.upload() exists
URL Launcher
[OK] ft.UrlLauncher exists (Service — needs overlay)
[!!] page.launch_url() is DEPRECATED — source says "Use UrlLauncher() instead"
Page JavaScript
[!!] page has no JavaScript methods (run_javascript / eval_javascript)
Confirmed via inspect.getsource(ft.Page.launch_url):
@deprecated("Use UrlLauncher().launch_url() instead.", version="0.90.0", ...)
async def launch_url(self, url, ...):
Root cause hypothesis
Service controls (FilePicker, UrlLauncher) require a JS-side listener to be registered via the WebSocket handshake. In web mode with server-side rendering, this handshake does not complete reliably — the Python server calls invoke_method before the JS client has registered the listener for that specific control instance. The timeout is hardcoded at 10 seconds, which is never reached in time.
In desktop mode this works because the Flutter engine is local and the listener registration is synchronous/immediate.
Workaround implemented
Replaced FilePicker entirely with a separate FastAPI microservice that serves a native HTML <input type="file"> form. The Flet app displays the form URL in a copyable TextField. The user opens it manually in a new browser tab, uploads the file, then returns to the Flet app and clicks a "Done" button that polls the microservice for the result.
This works but is clearly not acceptable UX for a production app.
Expected behavior
ft.FilePicker (and ft.UrlLauncher) should work in Flet web mode (server-side) the same way they work in desktop mode. The JS listener registration should complete before pick_files() / launch_url() is awaited.
Suggestions
- Add an
await picker.ensure_ready() or similar method that waits for the JS listener to register before calling pick_files().
- Or expose
page.run_javascript() / page.eval_javascript() to allow app-level workarounds.
- Or document clearly which controls do NOT work in web mode and provide the recommended alternative.
Additional details
page.run_javascript() / page.eval_javascript() do not exist on ft.Page in 0.81.0, so there is no way to work around this at the app level.
- The deprecation warning on
page.launch_url() pointing to version="0.90.0" suggests this is a known area of active change — is there an ETA for when UrlLauncher / FilePicker will work reliably in web mode?
Duplicate Check
Describe the bug
In Flet 0.81.0 web mode (server-side, Docker), all
Servicecontrols (FilePicker,UrlLauncher) fail to work.page.launch_url()is also deprecated and delegates toUrlLauncherinternally. There is no working way to open a native file dialog or launch a URL from a Flet web app in 0.81.0.Two distinct failure modes depending on how/when the control is registered:
Mode A — "Unknown control: FilePicker" (red error bar across all views)
Occurs when
FilePickeris added topage.overlaybefore or during the firstpage.update()— e.g., inmain(),MainLayout, orapp.py. The JS client doesn't recognize the control because the control tree handshake hasn't completed yet.Mode B —
TimeoutException after 10s: Timeout waiting for invoke method listenerOccurs when
FilePickeris created per-click (inside the button handler), added topage.overlay,page.update()called, thenawait picker.pick_files()called. The JS listener forFilePickernever registers in time.Environment
Reproduction (minimal)
All registration strategies attempted (all fail in web mode)
FilePickerglobal in shared stateFilePickerinMainLayout.did_mount()FilePickerper-click withoverlay.append()+update()TimeoutException after 10sFilePickerinmain()before firstnavigate()asyncio.sleep(0.3)beforepick_files()TimeoutException— sleep not enoughft.UrlLauncher().launch_url(url)page.launch_url(url)UrlLauncherinternallyDiagnostic output (
check_flet.py --compat)Confirmed via
inspect.getsource(ft.Page.launch_url):Root cause hypothesis
Servicecontrols (FilePicker,UrlLauncher) require a JS-side listener to be registered via the WebSocket handshake. In web mode with server-side rendering, this handshake does not complete reliably — the Python server callsinvoke_methodbefore the JS client has registered the listener for that specific control instance. The timeout is hardcoded at 10 seconds, which is never reached in time.In desktop mode this works because the Flutter engine is local and the listener registration is synchronous/immediate.
Workaround implemented
Replaced
FilePickerentirely with a separate FastAPI microservice that serves a native HTML<input type="file">form. The Flet app displays the form URL in a copyableTextField. The user opens it manually in a new browser tab, uploads the file, then returns to the Flet app and clicks a "Done" button that polls the microservice for the result.This works but is clearly not acceptable UX for a production app.
Expected behavior
ft.FilePicker(andft.UrlLauncher) should work in Flet web mode (server-side) the same way they work in desktop mode. The JS listener registration should complete beforepick_files()/launch_url()is awaited.Suggestions
await picker.ensure_ready()or similar method that waits for the JS listener to register before callingpick_files().page.run_javascript()/page.eval_javascript()to allow app-level workarounds.Additional details
page.run_javascript()/page.eval_javascript()do not exist onft.Pagein 0.81.0, so there is no way to work around this at the app level.page.launch_url()pointing toversion="0.90.0"suggests this is a known area of active change — is there an ETA for whenUrlLauncher/FilePickerwill work reliably in web mode?