# What changed in dash

> 30 changes in dash 4 from its official release notes, upgrade guides and advisories: 2 breaking, 1 deprecations, 1 security, 11 new APIs and options. Each one cited. Sources checked 2026-10-21. HTML: https://unstale.sh/pypi/dash/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## dash 4

### Breaking changes

- Python 3.8 support is dropped; Python 3.9 is now the minimum supported version. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- Removes the Dash() constructor argument; callback docstring exposure is now controlled via configure_mcp_server(expose_callback_docstrings=...). (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)

### Security

- 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. (4.4.1) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.1)

### Deprecations

- Registration now warns for synchronous persistent no-output callbacks because they would tie up a worker thread. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)

### New APIs and options

- Adds the `websocket_max_workers` argument to configure the shared thread pool for synchronous WebSocket callbacks; its default is `4`. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- MCP Tools now support background callbacks. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Formats callback results for LLM consumption, including rendered graphs and markdown tables. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Adds a way to represent callback-related data in an MCP-friendly format. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Adds a function to control which content the MCP server exposes. Only explicitly passed parameters are updated; omitted parameters retain their current value. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Adds an MCP Tool for getting a Dash component and executing callbacks. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Adds an MCP-related function decorator, alongside server routes and Streamable HTTP transport. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Adds support for exposing callbacks as MCP Tools. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- MCP Tools now support pattern-matching callbacks. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Adds resources for exposing app layout, components, and pages. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Adds Streamable HTTP transport for the MCP server. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)

### Behavior and default changes

- 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. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)

### Fixes and other changes

- Fixes a missing comm dependency. (4.4.1) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.1)
- 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. (4.4.1) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.1)
- The callback dispatch view is again exposed under this fully-qualified name, restoring Flask-WTF and Quart-WTF CSRF exemptions that use it. (4.4.1) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.1)
- All relayout changes are synced to the `figure` prop, preventing user interactions such as pan, zoom, and shape or annotation edits from being reverted by a subsequent Patch update. (4.4.1) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.1)
- Prevents `UnboundLocalError` when an async background callback using Celery or Diskcache raises `PreventUpdate` or another exception before `user_callback_output` is assigned. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- Synchronous WebSocket callbacks now inherit `ContextVar` values bound by ASGI middleware because context is captured on the event-loop thread before submission. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- Returns an empty list on non-Chrome webdrivers instead of `None`, allowing assertions such as checking for no logs to work consistently. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- Fixes teardown hanging when stopping a `ThreadedRunner` for Quart apps. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- Fixes `updatemode="bothdates"` not always being respected. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- Prevents `RuntimeError: No active request in context` when a non-Dash path falls through to the FastAPI catch-all route. (4.4.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.4.0)
- Fixes context serialization for non-dict request args on the FastAPI and Quart backends. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Fixes a deadlock caused by middleware consuming the request body. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Responds to Streamable HTTP GET (SSE) requests with an empty event stream instead of 405 Method Not Allowed. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
- Fixes websockets using an incorrect path when deployed behind a proxy. (4.3.0) — [release notes](https://github.com/plotly/dash/releases/tag/v4.3.0)
