From cce590e9f09a7e69a8b3eb073243ff5f7e81db29 Mon Sep 17 00:00:00 2001 From: "shuwen.wu" Date: Fri, 25 Sep 2026 11:56:58 +0800 Subject: [PATCH] fix: handle None return from error handler in no-output background callbacks When a background callback with no outputs raises an exception, the error handler is called. If the error handler returns None, the code was incorrectly setting output_value = NoUpdate(), which then triggered an InvalidCallbackReturnValue exception at the output validation step. This change adds the same output_spec check that exists in the non-background callback path (line 866) to the background callback path (line 635), ensuring that NoUpdate() is only set when there are actual outputs to update. Fixes plotly/dash#3628 --- dash/_callback.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dash/_callback.py b/dash/_callback.py index 1a24bdf621..c400a3c3a1 100644 --- a/dash/_callback.py +++ b/dash/_callback.py @@ -574,6 +574,7 @@ def _update_background_callback( kwargs, background, multi, + output_spec, cache_key=None, job_id=None, ): @@ -602,6 +603,7 @@ def _update_background_callback( error_handler, callback_ctx, multi, + output_spec, cache_key=cache_key, job_id=job_id, ) @@ -614,6 +616,7 @@ def _handle_rest_background_callback( error_handler, callback_ctx, multi, + output_spec, has_update=False, cache_key=None, job_id=None, @@ -632,7 +635,7 @@ def _handle_rest_background_callback( if error_handler: output_value = error_handler(exc) - if output_value is None: + if output_value is None and output_spec: output_value = NoUpdate() # set_props from the error handler uses the original ctx # instead of manager.get_updated_props since it runs in the @@ -852,7 +855,7 @@ def add_context(*args, **kwargs): ) output_value, has_update, skip = _update_background_callback( - error_handler, callback_ctx, response, kwargs, background, multi + error_handler, callback_ctx, response, kwargs, background, multi, output_spec ) if skip: return output_value @@ -923,7 +926,7 @@ async def async_add_context(*args, **kwargs): callback_ctx, ) output_value, has_update, skip = _update_background_callback( - error_handler, callback_ctx, response, kwargs, background, multi + error_handler, callback_ctx, response, kwargs, background, multi, output_spec ) if skip: return output_value