Skip to content

Fix UnboundLocalError in async background callbacks#3822

Open
i-murray wants to merge 2 commits into
plotly:devfrom
i-murray:fix/async-background-callback-unboundlocalerror
Open

Fix UnboundLocalError in async background callbacks#3822
i-murray wants to merge 2 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.
@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

2 participants