pypi / dash
dash
What changed in dash 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-21.
2 breaking1 security1 deprecations11 new APIs and options1 behavior and defaults14 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initdash 430 changes
Breaking changes 2
Python 3.8 support is dropped; Python 3.9 is now the minimum supported version.
Removes the Dash() constructor argument; callback docstring exposure is now controlled via configure_mcp_server(expose_callback_docstrings=...).
Security 1
Client-supplied job and cache handles are now HMAC-signed and bound to a per-page-load token, rejecting forged or replayed values that could terminate processes or access arbitrary result-cache entries.
Deprecations 1
Registration now warns for synchronous persistent no-output callbacks because they would tie up a worker thread.
New APIs and options 11
Adds the
websocket_max_workersargument to configure the shared thread pool for synchronous WebSocket callbacks; its default is4.MCP Tools now support background callbacks.
Formats callback results for LLM consumption, including rendered graphs and markdown tables.
Adds a way to represent callback-related data in an MCP-friendly format.
Adds a function to control which content the MCP server exposes. Only explicitly passed parameters are updated; omitted parameters retain their current value.
Adds an MCP Tool for getting a Dash component and executing callbacks.
Adds an MCP-related function decorator, alongside server routes and Streamable HTTP transport.
Adds support for exposing callbacks as MCP Tools.
MCP Tools now support pattern-matching callbacks.
Adds resources for exposing app layout, components, and pages.
Adds Streamable HTTP transport for the MCP server.
Behavior and default changes 1
Async WebSocket callbacks run directly on the connection event loop, while synchronous callbacks use a shared thread pool, so long-lived callbacks no longer limit concurrent users.
Fixes and other changes 14
Fixes a missing comm dependency.
Dash pre-registers the running main module under its canonical import name, preventing callbacks from being registered twice when a script is re-executed through an import string.
The callback dispatch view is again exposed under this fully-qualified name, restoring Flask-WTF and Quart-WTF CSRF exemptions that use it.
All relayout changes are synced to the
figureprop, preventing user interactions such as pan, zoom, and shape or annotation edits from being reverted by a subsequent Patch update.Prevents
UnboundLocalErrorwhen an async background callback using Celery or Diskcache raisesPreventUpdateor another exception beforeuser_callback_outputis assigned.Synchronous WebSocket callbacks now inherit
ContextVarvalues bound by ASGI middleware because context is captured on the event-loop thread before submission.Returns an empty list on non-Chrome webdrivers instead of
None, allowing assertions such as checking for no logs to work consistently.Fixes teardown hanging when stopping a
ThreadedRunnerfor Quart apps.Fixes
updatemode="bothdates"not always being respected.Prevents
RuntimeError: No active request in contextwhen a non-Dash path falls through to the FastAPI catch-all route.Fixes context serialization for non-dict request args on the FastAPI and Quart backends.
Fixes a deadlock caused by middleware consuming the request body.
Responds to Streamable HTTP GET (SSE) requests with an empty event stream instead of 405 Method Not Allowed.
Fixes websockets using an incorrect path when deployed behind a proxy.