Skip to content

Fix callbacks double-registered when app file is loaded by import string#3883

Merged
T4rk1n merged 4 commits into
devfrom
fix/double-register
Jul 15, 2026
Merged

Fix callbacks double-registered when app file is loaded by import string#3883
T4rk1n merged 4 commits into
devfrom
fix/double-register

Conversation

@T4rk1n

@T4rk1n T4rk1n commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

When the app module runs as a script, a server that loads it by import string (e.g. uvicorn.run("app:server", reload=True)) executes the same file twice in the worker process: multiprocessing spawn re-runs it as mp_main, then the import string imports it again under its real name. Both passes run the @callback decorators, duplicating every spec in _dash-dependencies and triggering "Duplicate callback outputs" errors in the renderer.

Dash() now pre-registers the running main module in sys.modules under its canonical import name (only when that name resolves to the same file and isn't already imported), so the second import reuses the already-executed module instead of re-executing the file.

Fixes #3818

When the app module runs as a script, a server that loads it by import
string (e.g. uvicorn.run("app:server", reload=True)) executes the same
file twice in the worker process: multiprocessing spawn re-runs it as
__mp_main__, then the import string imports it again under its real
name. Both passes run the @callback decorators, duplicating every spec
in _dash-dependencies and triggering "Duplicate callback outputs"
errors in the renderer.

Dash() now pre-registers the running main module in sys.modules under
its canonical import name (only when that name resolves to the same
file and isn't already imported), so the second import reuses the
already-executed module instead of re-executing the file.

Fixes #3818

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@camdecoster camdecoster left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a couple of suggestions. The CHANGELOG entry is missing the PR number.

Comment thread dash/dash.py Outdated
):
sys.modules[import_name] = module
except (ImportError, ValueError, OSError):
pass

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should a warning be logged here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment explaining why it's needed.

Comment thread CHANGELOG.md Outdated
@sonarqubecloud

Copy link
Copy Markdown

@T4rk1n T4rk1n merged commit f2f3151 into dev Jul 15, 2026
29 checks passed
@T4rk1n T4rk1n deleted the fix/double-register branch July 15, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Callbacks double-registered when using uvicorn --reload under backend="fastapi"

2 participants