Skip to content

Fix UnboundLocalError in async background callbacks#3822

Merged
T4rk1n merged 3 commits into
plotly:devfrom
i-murray:fix/async-background-callback-unboundlocalerror
Jun 25, 2026
Merged

Fix UnboundLocalError in async background callbacks#3822
T4rk1n merged 3 commits into
plotly:devfrom
i-murray:fix/async-background-callback-unboundlocalerror

Conversation

@i-murray

@i-murray i-murray commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

In the async_run() path of the Celery and Diskcache background callback managers, user_callback_output was referenced after the try/except block without being initialised. When an async callback raised PreventUpdate or another exception, control skipped the assignment and the subsequent asyncio.iscoroutine(user_callback_output) check raised UnboundLocalError, masking the original error.

Initialise user_callback_output to None before the try block and only evaluate the coroutine check when no error occurred. Add unit tests that exercise the generated job functions directly for the success, exception and PreventUpdate paths.

Closes #3821

Contributor Checklist

  • I have broken down my PR scope into the following TODO tasks
    • Fix dash/background_callback/managers/celery_manager.py & dash/background_callback/managers/diskcache_manager.py
  • I have run the tests locally and they passed. (refer to testing section in contributing)
  • I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR
    • Additional tests: tests/unit/test_async_background_callback_job_fn.py

optionals

  • I have added entry in the CHANGELOG.md

In the async_run() path of the Celery and Diskcache background callback
managers, user_callback_output was referenced after the try/except block
without being initialised. When an async callback raised PreventUpdate or
another exception, control skipped the assignment and the subsequent
asyncio.iscoroutine(user_callback_output) check raised UnboundLocalError,
masking the original error.

Initialise user_callback_output to None before the try block and only
evaluate the coroutine check when no error occurred. Add unit tests that
exercise the generated job functions directly for the success, exception
and PreventUpdate paths.

@T4rk1n T4rk1n 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.

💃

@T4rk1n T4rk1n merged commit 60b7711 into plotly:dev Jun 25, 2026
28 checks passed
@sonarqubecloud

Copy link
Copy Markdown

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] UnboundLocalError: user_callback_output in async background callbacks when callback raises an exception or PreventUpdate

3 participants