# Callback mysteriously stopped working

**URL:** <https://community.plotly.com/t/callback-mysteriously-stopped-working/33016>\
**Category:** Dash Python\
**Created:** [December 27, 2019, 5:43pm UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016 "2019-12-27T17:43:26Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![bebuck](https://avatars.discourse-cdn.com/v4/letter/b/57b2e6/32.png) [@bebuck](https://community.plotly.com/u/bebuck)\
**Post date:** [December 27, 2019, 5:43pm UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/1 "2019-12-27T17:43:26Z")

</div>

Unfortunately, I don’t know what I changed in the code that would cause this callback to stop working.

This callback works like a champ:

```auto
@app.callback(
    dash.dependencies.Output('selecteddie', 'style'),
    [dash.dependencies.Input('refresh', 'n_clicks')]
)
def worknow(refreshdata):
    print('WORKNOW!', refreshdata)
    raise PreventUpdate

```

This callback refuses to acknowledge that button ‘refresh’ has ever been pushed:

```auto
@app.callback(
    [
        dash.dependencies.Output('Bin_Wafermap', 'figure'),
        dash.dependencies.Output('selecteddie', 'children'),
        dash.dependencies.Output('dbstate', 'children'),
        dash.dependencies.Output('dbstate', 'style')
    ],
    [dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('Bin_Wafermap', 'clickData'),
     dash.dependencies.Input('idwafer', 'value'),
     dash.dependencies.Input('product', 'value'),
     dash.dependencies.Input('subproduct', 'value'),
     dash.dependencies.Input('idlot', 'value'),
     ]
)
def update_click_data(refreshdata, clickData, wfrval, myprod, subprod, mylot):
    print("LAUNCH THE CALLBACK", refreshdata)
    raise PreventUpdate

```

why did my callback stop working? I tried to strip everything out of it, Dash still pretends that it doesn’t exist anymore ☹

---

<div class="post-metadata">

**Author:** ![bebuck](https://avatars.discourse-cdn.com/v4/letter/b/57b2e6/32.png) [@bebuck](https://community.plotly.com/u/bebuck)\
**Post date:** [December 27, 2019, 6:37pm UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/2 "2019-12-27T18:37:07Z")

</div>

Also tried rebooting and updating DASH with pip. Also of note: I have “debounce” on for the text input boxes but also tried turning “debounce” off and in both cases the text input boxes DO call the callback.

Thanks, – Ben

---

<div class="post-metadata">

**Author:** ![Emmanuelle](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/emmanuelle/32/7853_2.png) [@Emmanuelle](https://community.plotly.com/u/Emmanuelle)\
**Post date:** [December 27, 2019, 9:31pm UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/3 "2019-12-27T21:31:52Z")

</div>

Hi @bebuck, could you please share a complete standalone app (including layout in particular) so that we can reproduce the issue? Do you execute the app with `debug=True` and if yes, are there any error messages?

---

<div class="post-metadata">

**Author:** ![bebuck](https://avatars.discourse-cdn.com/v4/letter/b/57b2e6/32.png) [@bebuck](https://community.plotly.com/u/bebuck)\
**Post date:** [December 28, 2019, 12:07am UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/4 "2019-12-28T00:07:48Z")

</div>

Thanks for the response. Here’s what I’m running, and there are no messages from DASH; the Callback launches properly for everything but two of the buttons, “do access” and “verify state”

```auto
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.exceptions import PreventUpdate
import pandas as pd
import plotly.graph_objs as go

app = dash.Dash( __name__ )

sample_colormap = [[0.0, 'black'],[0.1,'black'],[0.1,'yellow'],[0.2, 'yellow'],[0.2,'orange'],[0.4,'orange'],[0.4,'green'],
                   [0.6,'green'],[0.6,'red'],[0.8,'red'],[0.8,'blue'],[1,'blue'], [1, 'brown']]

basedir = r'c:\temp' + '\\'

def initialize_storedata(curwafer='No Wafer'):
    serializable = {
        'Wafergz': [],
        'ROW': [],
        'COL': [],
        'Claimed': [],
        'Comment': []
    },
    wafertable = {
        'LOT': [],
        'WAFER_ID': []
    }
    storedata = {'loading': False, 'scratchsrc': serializable, 'curwafer': curwafer, 'fireup': False,
                 'lastx': None, 'lasty': None, 'refreshclicks': 0, 'subproducts': {'': []}, 'dbstate': False,
                 'subdefvals': {'': ''}, 'myprods': [], 'defval': '', 'lotlist': [], 'wafertable': wafertable}
    return storedata

app.layout = html.Div([
    dcc.Store(id='memory'),
    html.Div([
        dcc.Input(
            id='input_username',
            type='text',
            placeholder='Username',
            debounce=True,
            size='50'
        ),
        dcc.Input(
            id='input_password',
            type='password',
            placeholder='Password',
            debounce=True,
            size='50'

        ),
        html.Button('Do Access', id='dosomething')
    ]),
    html.Div([
        dcc.Dropdown(
            id='product',
            options=[],
            value=''
        )
    ]),
    html.Div([
        dcc.Dropdown(
            id='subproduct',
            options=[],
            value=''
        )
    ]),
    html.Div([
        dcc.Dropdown(
            id='idlot',
            options=[],
            value=''
        )
    ]),
    html.Div([
        dcc.Dropdown(
            id='idwafer',
            options=[],
            value=''
        )
    ]),
    html.Div(html.Button('Verify State', id='refresh'), id='refbutton'),
    html.Div(['Not successfully logged on to thesytem'], id='dbstate', style={'color': 'red'}),
    html.Div(id='grossreality'),
    html.Div(id='selecteddie'),
    html.Div(id='emptybox'),
    html.Div(id='emptyboxtwo'),
    html.Div(id='emptyboxthree'),
    html.Div([
    dcc.Graph(
        id='Bin_Wafermap',
        figure={
            'data': [
                {
                    'y': [0, 0, 1, 1],
                    'x': [0, 1, 0, 1],
                    'text': ['A', 'B', 'C', 'D'],
                    'type': 'scatter',
                    'mode': 'markers+text',
                    'marker':
                    {
                        'symbol': ['square'] * 4,
                        'size': [24] * 4,
                        'colorscale': sample_colormap,
                        'color': [1] * 4,
                        'cmin': 0,
                        'cmax': 1
                    }
                }
            ],
            'layout': go.Layout(
                xaxis={'title': 'ROW', 'visible': False},
                yaxis={'title': 'COL', 'visible': False},
                margin={'l': 150, 'b': 50, 't': 10, 'r': 10},
                legend={'x': 1, 'y': 0},
                hovermode='closest',
                clickmode='event+select',
                height=720,
                width=960
            )
        }
    )
    ]),
    html.Div([html.Button('Claim Die', id='dieclaim'),
              html.Button('Leave Comment', id='diecomment')], id='claimbutton'),
    html.Div(dcc.Input(id='commentsdata', type='text', debounce=True, size='120'))
    ])

@app.callback(
    [dash.dependencies.Output('product', 'options'),
     dash.dependencies.Output('subproduct', 'options'),
     dash.dependencies.Output('subproduct', 'value')],
    [dash.dependencies.Input('product', 'value'),
     dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('dosomething', 'n_clicks')],
    [dash.dependencies.State('memory', 'data')]
)
def update_products_and_subproducts(value, refbutton, pwbutton, storedata):
    if storedata is None:
        storedata = initialize_storedata()
    if not storedata['fireup']:
        raise PreventUpdate
    if value in storedata['subproducts'] and value in storedata['subdefvals']:
        return storedata['myprods'], storedata['subproducts'][value], storedata['subdefvals'][value]
    else:
        return storedata['myprods'], [], ''

@app.callback(
    dash.dependencies.Output('product', 'value'),
    [dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('dosomething', 'n_clicks')],
    [dash.dependencies.State('memory', 'data')]
)
def update_product_value(refbutton, pwbutton, storedata):
    if storedata is None:
        storedata = initialize_storedata()
    if not storedata['fireup']:
        raise PreventUpdate
    return storedata['defval']

@app.callback(
    [dash.dependencies.Output('idlot', 'options'),
     dash.dependencies.Output('idlot', 'value')],
    [dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('product', 'value'),
     dash.dependencies.Input('subproduct', 'value'),
     dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('dosomething', 'n_clicks')],
    [dash.dependencies.State('memory', 'data')]
)
def update_lots(refreshdata, value, subvalue, refresh, pwbutton, storedata):
    if storedata is None:
        storedata = initialize_storedata()
    if not storedata['fireup']:
        raise PreventUpdate
    if value is None:
        value = ''
    if subvalue is None:
        subvalue = ''
    raise PreventUpdate

@app.callback(
    [dash.dependencies.Output('idwafer', 'options'),
     dash.dependencies.Output('idwafer', 'value')
        ],
    [dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('product', 'value'),
     dash.dependencies.Input('subproduct', 'value'),
     dash.dependencies.Input('idlot', 'value')],
    [dash.dependencies.State('memory', 'data')]
)
def update_wafers(refreshdata, value, subvalue, lotvalue, storedata):
    if storedata is None:
        storedata = initialize_storedata()
    if not storedata['fireup']:
        raise PreventUpdate
    wafertable = pd.DataFrame(storedata['wafertable'])
    waferlist = wafertable[wafertable.LOT == lotvalue]['WAFER_ID'].unique()
    if value is None:
        value = ''
    if subvalue is None:
        subvalue = ''
    if lotvalue is None:
        lotvalue = ''
    raise PreventUpdate

@app.callback(
    [dash.dependencies.Output('grossreality', 'children'),
     dash.dependencies.Output('grossreality', 'style')
     ],
    [dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('idlot', 'value'),
     dash.dependencies.Input('idwafer', 'value')],
    [dash.dependencies.State('memory', 'data')]
)
def checkrealitystate(refreshdata, lotvalue, wafervalue, storedata):
    if storedata is None:
        storedata = initialize_storedata()
    if lotvalue is None:
        lotvalue = ""
    if wafervalue is None:
        wafervalue = ""
    if str(lotvalue) + ' ' + str(wafervalue) != storedata['curwafer'] or storedata['validity'] == 'False' \
            or len(storedata['curwafer']) < 3:
        return 'Please Click Verify State before proceeding to ensure page is ready (if it doesn\'t respond, it isn\'t.)', {'color': 'red'}
    else:
        return 'Now showing:' + str(storedata['curwafer']), {'color': 'black'}

@app.callback(
    dash.dependencies.Output('emptybox', 'style'),
    [dash.dependencies.Input('refresh', 'n_clicks')]
)
def worknow(refreshdata):
    print('The Verify Button Successfully fired the alt callback', refreshdata)
    raise PreventUpdate

@app.callback(
    dash.dependencies.Output('emptyboxtwo', 'style'),
    [dash.dependencies.Input('dosomething', 'n_clicks')]
)
def worknowtwo(refreshdata):
    print('The Do Something Button Successfully fired the alt callback', refreshdata)
    raise PreventUpdate

@app.callback(
    dash.dependencies.Output('emptyboxthree', 'style'),
    [dash.dependencies.Input('dieclaim', 'n_clicks')]
)
def worknowthree(refreshdata):
    print('The Dieclaim Button Successfully fired the alt callback', refreshdata)
    raise PreventUpdate

@app.callback(
    [
        dash.dependencies.Output('memory', 'data'),
        dash.dependencies.Output('Bin_Wafermap', 'figure'),
        dash.dependencies.Output('selecteddie', 'children')
    ],
    [dash.dependencies.Input('refresh', 'n_clicks'),
     dash.dependencies.Input('Bin_Wafermap', 'clickData'),
     dash.dependencies.Input('idwafer', 'value'),
     dash.dependencies.Input('product', 'value'),
     dash.dependencies.Input('subproduct', 'value'),
     dash.dependencies.Input('idlot', 'value'),
     dash.dependencies.Input('dieclaim', 'n_clicks'),
     dash.dependencies.Input('diecomment', 'n_clicks'),
     dash.dependencies.Input('commentsdata', 'value'),
     dash.dependencies.Input('dosomething', 'n_clicks'),
     dash.dependencies.Input('input_username', 'value'),
     dash.dependencies.Input('input_password', 'value')
     ],
    [dash.dependencies.State('memory', 'data')]
)
def update_click_data(refreshdata, clickData, wfrval, myprod, subprod, mylot, dieclaim, diecomments, commentsdata, pwclicks, username, password, storedata):
    print("LAUNCH THE CALLBACK rfbutton", refreshdata, "dieclaim", dieclaim, "diecomments", diecomments, 'pwclicks', pwclicks)
    raise PreventUpdate

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

```

---

<div class="post-metadata">

**Author:** ![Emmanuelle](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/emmanuelle/32/7853_2.png) [@Emmanuelle](https://community.plotly.com/u/Emmanuelle)\
**Post date:** [December 28, 2019, 3:30am UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/5 "2019-12-28T03:30:14Z")

</div>

There might be a problem with your callback graph: see below the image obtained with the developers tools (click on the blue button on the bottom-right corner of your app). The `refresh` button triggers the callback modifying `grossreality` but also a callback modifying `idwafer` and another one modifying `idlot`, which can in turn modify grossreality. I think it is hard for Dash to know in which order to trigger these callbacks. The same situation happens for the `dosomething` button. Probably you need to simplify the graph of callbacks so that there is a single path starting from `refresh` to modify `grossreality` (and the same for `dosomething`).

 ![image](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/0/09cb80cef5c833b7a57b3962dac81224c00d0ecb.png)

---

<div class="post-metadata">

**Author:** ![bebuck](https://avatars.discourse-cdn.com/v4/letter/b/57b2e6/32.png) [@bebuck](https://community.plotly.com/u/bebuck)\
**Post date:** [December 28, 2019, 5:08pm UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/6 "2019-12-28T17:08:37Z")

</div>

In the spirit of “if you don’t ask it won’t happen”, is there a way to make ALL the callbacks run that consume data out of [dash.dependencies.State(‘memory’, ‘data’)] ANY time values change in that? (possibly excepting the one callback that has the privileges to update [dash.dependencies.State(‘memory’, ‘data’)].) That alone would make unnecessary and simplify down my callback chain. Thanks.

---

<div class="post-metadata">

**Author:** ![Emmanuelle](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/emmanuelle/32/7853_2.png) [@Emmanuelle](https://community.plotly.com/u/Emmanuelle)\
**Post date:** [December 28, 2019, 9:19pm UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/7 "2019-12-28T21:19:46Z")

</div>

Hum, if you want callbacks to run when a component changes, I dont’ understand why you don’t put it as `Input` (instead of `State`)? The distinction exists so that an `Input` triggers the callback to run, while a `State` can be passed as a variable but will not trigger the callback. What am I missing 🙂 ?

---

<div class="post-metadata">

**Author:** ![bebuck](https://avatars.discourse-cdn.com/v4/letter/b/57b2e6/32.png) [@bebuck](https://community.plotly.com/u/bebuck)\
**Post date:** [December 29, 2019, 1:11pm UTC](https://community.plotly.com/t/callback-mysteriously-stopped-working/33016/8 "2019-12-29T13:11:10Z")

</div>

I didn’t realize you could do that. Once I rename Input to State and State to Input on dash.dependencies, it seems to correct the issue, thanks
