🚀 Gen 5 of the leading AI app deployment platform launches October 6. Click for the livestream.

Dash Core Components callback error

Hello Dash community,

after the discussion here I ran into the following problem:
I updated my dash-core-components to the newest version. It seems like from version 0.10.0 upwards there is a new behaviour handling inputs and outputs in app callbacks.
Until version 0.10.0 I was able to store intermediate results into a hidden div and use this div as an input to multiple other callbacks. Each time the value of the intermediate div changed, the corresponding app callback was triggered.
Now this isn’t working any more. The result can still be stored into a hidden div but this does not trigger the next callback.

This was working before, but now it doesn’t (some-value-ui-state is a div):

@app.callback(
    Output('some-value-ui-state', 'children'),
    [Input('input-folder', 'value')])
def update_some_value_ui_state(folder):
    if folder:
        return some_function(folder)


@app.callback(
    Output('input-factors', 'options'),
    [Input('some-value-ui-state', 'children')])
def update_input_factor_options(value):
    return do_something_else()

There is always an error in the bundle.js when the intermediate div tries to update the next output. The whole executioon of all callbacks on the page breaks at this point.

My whole layout is served within a function like in the example “Updates on Page Load” . I also use the location component to serve different pages on different URLs. Therefore the app is configured with app.config.supress_callback_exceptions = True.

I am thankful for every hint!

Thanks for reporting! I’m having a hard time reproducing the issue. I’ve created a minimal example:

import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
import datetime

print(dcc.__version__)

def serve_layout():
    return html.Div([
        html.Div(id='state-container', style={'display': 'none'}),
        html.Div(id='output'),
        dcc.Dropdown(id='dropdown', options=[{'label': i, 'value': i} for i in ['A', 'B']])
    ])

app = dash.Dash()

app.layout = serve_layout

app.config.supress_callback_exceptions = True

@app.callback(
    Output('state-container', 'children'),
    [Input('dropdown', 'value')])
def update_state(value):
    return 'You have selected "{}"'.format(value)


@app.callback(
    Output('output', 'children'),
    [Input('state-container', 'children')])
def update_output(value):
    return value


if __name__ == '__main__':
    app.run_server()

That works on v0.12.3 of dash-core-components. Does this example work for you? If so, could you modify this example to a point that demonstrates the bug?

Thanks!

Thank you for offering your time!

It took me an hour now to reproduce the “bug”. It turned out that it is not the fault of the app callback itself.
But the error was almost visible in the code I postet.

The problem is this part of the callback:

if folder:
    return some_function(folder)

It seems like as if the intermediate div is the input for another dropdown and the return value is empty, the whole execution of the event chain breaks.
Here is my modified code:

import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
import datetime

print(dcc.__version__)

def serve_layout():
    return html.Div([
        html.Div(id='state-container', style={'display': 'none'}),
        dcc.Dropdown(id='dropdown', options=[{'label': i, 'value': i} for i in ['A', 'B']]),
        dcc.Dropdown(id='output')
    ])

app = dash.Dash()

app.layout = serve_layout

app.config.supress_callback_exceptions = True

@app.callback(
    Output('state-container', 'children'),
    [Input('dropdown', 'value')])
def update_state(value):
    if value:
        return 'You have selected "{}"'.format(value)


@app.callback(
    Output('output', 'options'),
    [Input('state-container', 'children')])
def update_output(value):
    if value:
        return [{'label': i, 'value': i} for i in ['C', 'D']]


if __name__ == '__main__':
    app.run_server()

I can confirm that the modified code posted above by @HansG still does not work in version 0.18.1. @chriddyp, have you had an opportunity to investigate this issue?

It looks like the issue is that the options property of the dropdown fails when a callback updates it with None. Changing the second callback to

@app.callback(
    Output('output', 'options'),
    [Input('state-container', 'children')])
def update_output(value):
    if value:
        return [{'label': i, 'value': i} for i in ['C', 'D']]
    else:
        return [{}]

fixes the issue.

1 Like

Hi,
I have the same problem. it didn’t get fix when I applied the changes that you did.