# Buggy code
def add_context(*args, **kwargs):
    # don't touch the comment on the next line - used by debugger
    output_value = func(*args, **kwargs)  # %% callback invoked %%
    if multi:
        if not isinstance(output_value, (list, tuple)):
            raise exceptions.InvalidCallbackReturnValue(
                "The callback {} is a multi-output.\n"
                "Expected the output type to be a list"
                " or tuple but got {}.".format(callback_id, repr(output_value))
            )

        if not len(output_value) == len(output):
            raise exceptions.InvalidCallbackReturnValue(
                "Invalid number of output values for {}.\n Expected {} got {}".format(
                    callback_id, len(output), len(output_value)
                )
            )

        component_ids = collections.defaultdict(dict)
        has_update = False
        for i, o in enumerate(output):
            val = output_value[i]
            if val is not no_update:
                has_update = True
                o_id, o_prop = o.component_id, o.component_property
                component_ids[o_id][o_prop] = val

        if not has_update:
            raise exceptions.PreventUpdate

        response = {"response": component_ids, "multi": True}
    else:
        if output_value is no_update:
            raise exceptions.PreventUpdate

        response = {"response": {"props": {output.component_property: output_value}}}

    try:
        jsonResponse = json.dumps(response, cls=plotly.utils.PlotlyJSONEncoder)
    except TypeError:
        self._validate_callback_output(output_value, output)
        raise exceptions.InvalidCallbackReturnValue(
            dedent(
                """
                    The callback for property `{property:s}`
                    of component `{id:s}` returned a value
                    which is not JSON serializable.

                    In general, Dash properties can only be
                    dash components, strings, dictionaries, numbers, None,
                    or lists of those.
                    """
            ).format(
                property=output.component_property,
                id=output.component_id,
            )
        )

    return jsonResponse


# Traceback (TypeError)
Exception on /_dash-update-component [POST]
Traceback (most recent call last):
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/dash/dash.py", line 1328, in add_context
response, cls=plotly.utils.PlotlyJSONEncoder
File "/home/kz/.local/pyenv/versions/3.7.3/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/_plotly_utils/utils.py", line 44, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File "/home/kz/.local/pyenv/versions/3.7.3/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/home/kz/.local/pyenv/versions/3.7.3/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/_plotly_utils/utils.py", line 113, in default
return _json.JSONEncoder.default(self, obj)
File "/home/kz/.local/pyenv/versions/3.7.3/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type _NoUpdate is not JSON serializable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/dash/dash.py", line 1404, in dispatch
response.set_data(self.callback_map[output]["callback"](*args))
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/dash/dash.py", line 1331, in add_context
self._validate_callback_output(output_value, output)
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/dash/dash.py", line 1187, in _validate_callback_output
_validate_value(output_value)
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/dash/dash.py", line 1180, in _validate_value
toplevel=True,
File "/home/kz/Envs/dash_bleedingedge/lib/python3.7/site-packages/dash/dash.py", line 1125, in _raise_invalid
bad_val=bad_val,
dash.exceptions.InvalidCallbackReturnValue:
The callback for `<Output `approot.children`>`
returned a value having type `_NoUpdate`
which is not JSON serializable.

The value in question is either the only value returned,
or is in the top level of the returned list,
and has string representation
`<dash.dash._NoUpdate object at 0x7ff2ca37ccf8>`

In general, Dash properties can only be
dash components, strings, dictionaries, numbers, None,
or lists of those.

# Fixed code
def add_context(*args, **kwargs):
    # don't touch the comment on the next line - used by debugger
    output_value = func(*args, **kwargs)  # %% callback invoked %%
    if multi:
        if not isinstance(output_value, (list, tuple)):
            raise exceptions.InvalidCallbackReturnValue(
                "The callback {} is a multi-output.\n"
                "Expected the output type to be a list"
                " or tuple but got {}.".format(callback_id, repr(output_value))
            )

        if not len(output_value) == len(output):
            raise exceptions.InvalidCallbackReturnValue(
                "Invalid number of output values for {}.\n Expected {} got {}".format(
                    callback_id, len(output), len(output_value)
                )
            )

        component_ids = collections.defaultdict(dict)
        has_update = False
        for i, o in enumerate(output):
            val = output_value[i]
            if not isinstance(val, _NoUpdate):
                has_update = True
                o_id, o_prop = o.component_id, o.component_property
                component_ids[o_id][o_prop] = val

        if not has_update:
            raise exceptions.PreventUpdate

        response = {"response": component_ids, "multi": True}
    else:
        if isinstance(output_value, _NoUpdate):
            raise exceptions.PreventUpdate

        response = {"response": {"props": {output.component_property: output_value}}}

    try:
        jsonResponse = json.dumps(response, cls=plotly.utils.PlotlyJSONEncoder)
    except TypeError:
        self._validate_callback_output(output_value, output)
        raise exceptions.InvalidCallbackReturnValue(
            dedent(
                """
                    The callback for property `{property:s}`
                    of component `{id:s}` returned a value
                    which is not JSON serializable.

                    In general, Dash properties can only be
                    dash components, strings, dictionaries, numbers, None,
                    or lists of those.
                    """
            ).format(
                property=output.component_property,
                id=output.component_id,
            )
        )

    return jsonResponse