Callback is displaying buttons that exist no where in my code

Hi,

I’m currently making an interactive survey that has to do with recording selection events from a scatter plot. Everything works perfectly except this one bug where when I select more than a certain number of points on the scatter plot, two buttons that i had in place a while back but no longer exist in the code, are displayed.

Oddly, it does not throw any errors when this happens. I’ve ctrl f’ed to look for the buttons in my codes by their names and they 100% are not there. How is this possible?

Even more so, I emailed the code to my other computer to see if it still happened. No luck there.

The callback input that triggers this is ‘selectedData’. Here’s my code for the layout and the callback. As you can see the buttons aren’t there.

app.layout = html.Div([


html.H1([
    html.Img(src=app.get_asset_url('logo2.png'), style = {'height':'25%', 'width':'25%'}),
    ], style={'textAlign':'center',"display": "block","margin-left":"auto","margin-right":"auto",'padding-top': 20}
),

html.Hr(style = {'background-color': '#6c1420', 'height': 10, 'border-color': '#6c1420', 'margin': 0, 'width': '100%'}),
html.H1(' ', style = {'height': '2vh'}), # 50

html.Div([ 
dcc.Tabs(id = 'tabs', value = 'tab1', vertical = True, children = [
    
    # Tab 1 - Information Collection
    dcc.Tab(id = 'tab1', label = 'Info', value = 'tab1', disabled = False, children = [
         
        html.Div([
        html.H3('Personal Information', style = {'font-weight': 'bold', 'textAlign':'left', "display": "block","margin-left":"auto","margin-right":"auto"}),
        html.H6('Name'),
        dcc.Input(
            id = 'name',
            placeholder = 'Name: John Doe',
            type = 'text',
            value  = '',
            style = {'textAlign':'left'}
        ),
        html.H6('Email'),
        dcc.Input(
            id = 'email',
            placeholder = 'Email: johndoe@gmail.com',
            type = 'text',
            value  = ''
        ),
        html.H1(' '),
        html.H1(' '),
        html.H3('Experience', style = {'font-weight': 'bold'}),
        html.H6('Background'),
        dcc.RadioItems(
            id = 'professional-experience',
            options = [
                {'label': 'Industry', 'value': 'indsutry'},
                {'label': 'Academic', 'value': 'academic'},
                {'label': 'Student', 'value': 'student'},
                {'label': 'Other', 'value':'other'}
            ],
        ),
        html.H1(' '),
        html.H6('Have you worked with bond data before?'),
        dcc.RadioItems(
            id = 'bond-experience',
            options=[
                {'label': 'Yes', 'value': 'yes'},
                {'label': 'No', 'value': 'n'}
            ],
        ),
        html.H1(' '),
        html.Div([
            html.Button('Begin Survey', id='begin-survey', style = {'font-size': '100%'})
        ]),
    ], style = {'textAlign':'left', "display": "block", 'padding-right': 200, 'padding-left': 25, 'border-color': '#6c1420'})
    ]),
    
    # Tab 2 - The Actual Survey, might make this the 3rd tab and add an additional tab that includes a basic tutorial / motivation for this survey
    dcc.Tab(id = 'tab2', label = 'Survey', value ='tab2', disabled=True , children = [

        html.Div([
            dcc.Graph(
                id='indicator-graphic',
                style={
                    'height': '45vh',
                    'width': '90vh',
                    "display": "block",
                    "margin-left": "auto",
                    "margin-right": "auto"
                },
                config = {'scrollZoom': True}
            ),

            html.Div([dcc.RadioItems(
                id = 'order-type',
                options = [{'label': i, 'value': i} for i in ['Buy', 'Sell','Both']],
                value = 'Both',
                labelStyle = {'display': 'inline-block'},
                style = {
                    'textAlign': 'center',
                    "display": "block",
                    "margin-left": "auto",
                    "margin-right": "auto",})]
            ),
            
            html.Div([
                html.Div([
                    html.Button('Confirm Selection', id='confirm-button', n_clicks = 0, style = {'font-size': '100%'})
                    ]),
                ], style={'textAlign':'center',"display": "block","margin-left":"auto","margin-right":"auto"}
            ),
            
            html.Div(id='index-log', style = {'display':'none'}),
            html.Div(id='hidden', style = {'display':'none'}),
            html.Div(id = 'show-table')   
            ], style = { "display": "block", 'padding-right': 100} # or 100, OCD trigger lmao
        )   
    ]),
    
    # Final Tab - Summarize Information as well as provide information about me and prof / our university
    dcc.Tab(id = 'tab3', label = 'Summary', value ='tab3', disabled=True , children = [ 
        html.Div(id = 'codex-index', style = {'display':'none'}),
        html.Div(id = 'dump', style = {'display':'none'}),
        html.Div(id = 'formatted')
    ])
    ], colors={"primary": '#6c1420'}),

    html.H1(' ', style = {'height': 50}), 

], style={'textAlign':'center',"display": "block","margin-left":"auto","margin-right":"auto"}),

# https://stackoverflow.com/questions/6127621/keeping-footer-at-the-bottom-of-window-on-site-that-scrolls-horizontal
html.Footer(style = {'display':'block', 'background-color': '#6c1420', 'height': '3vh', 'margin-top': '10vh'}) 

], style = {'height': '100vh', 'width': '100vw'}

)

@app.callback(
[Output(‘index-log’,‘children’),
Output(‘codex-index’,‘children’),
Output(‘show-table’,‘children’)],
[Input(‘indicator-graphic’,‘selectedData’),
Input(‘order-type’, ‘value’),
Input(‘confirm-button’,‘n_clicks’),
Input(‘tabs’,‘value’)],
[State(‘hidden’,‘children’),
State(‘index-log’,‘children’),
State(‘dump’,‘children’)]
)
def update_table(selected_data, order_type, conf_button, tab, hidden, current, prev_inds):

if prev_inds == None:
    PREV = []
else:
    prev_inds = json.loads(prev_inds)
    PREV = prev_inds['inds']

if conf_button < len(ids):
         
    if selected_data != None:

        if selected_data['points'] != []:
         
            # type manipulation for prev/next functionality
            if conf_button == None:
                conf_button = 0
            click_tracker = conf_button 
             
            # mapping pointNumber to index of global DataFrame
            buy = df[(df['bond_sym_id'] == ids[click_tracker]) & (df['rpt_side_cd'] == 'B')]
            sell = df[(df['bond_sym_id'] == ids[click_tracker]) & (df['rpt_side_cd'] == 'S')]

            fig_data = pd.DataFrame(selected_data["points"])[['curveNumber','pointNumber','y','text']]

            hidden = json.loads(hidden)
            B = hidden['buy']
            S = hidden['sell']

            curve_buy = fig_data[(fig_data['curveNumber'] == 0) & ((fig_data['pointNumber']).isin(B) == False)]
            curve_sell = fig_data[(fig_data['curveNumber'] == 1) & ((fig_data['pointNumber']).isin(S) == False)]
                    
            if max(list(curve_buy['pointNumber'].values)+[-1]) < len(buy) and max(list(curve_sell['pointNumber'].values)+[-1]) < len(sell):
                # collecting indicies 
                b = list(buy.iloc[curve_buy['pointNumber'].values]['hold_index'].values)
                s = list(sell.iloc[curve_sell['pointNumber'].values]['hold_index'].values)        
                indicies = b+s

                # manipulation for dataTable format
                DT = df.loc[indicies]
                DT['Datetime'] = DT['datetime']
                DT['Price'] = DT['rptd_pr']
                DT['Volume'] = DT['entrd_vol_qt']
                DT['B/S'] = DT['rpt_side_cd']
                DT = DT[['Datetime','Price','Volume','B/S']]

                # returning dataTable
                return [json.dumps({'buy': curve_buy['pointNumber'].values.tolist(), 'sell': curve_sell['pointNumber'].values.tolist()}, default=default), json.dumps({'inds':indicies}, default=default), \
                    html.Div([dash_table.DataTable( \
                        id = 'table', \
                        columns = [{"name": i, "id": i} for i in DT.columns], \
                        data = DT.to_dict("rows"), \
                        style_cell = {'textAlign': 'center','padding': '5px'}, \
                        style_as_list_view = True, \
                        style_cell_conditional=[{'if': {'column_id': 'Datetime'},'width': '100px'},{'if': {'column_id': 'Price'},'width': '100px'},{'if': {'column_id': 'Volume'},'width': '100px'}], \
                        style_header = {'backgroundColor': 'white', 'fontWeight': 'bold'}, \
                        n_fixed_rows = 1, \
                        style_table={'height': '20vh', 'width': '50vw', 'maxHeight': '300px', 'maxWidth': '500px',"margin-left": "auto", "margin-right": "auto"})])
                    ]
            else:
                return [json.dumps({'buy': [], 'sell': []}), json.dumps({'inds': PREV}, default=default),'']
        else:
            return [json.dumps({'buy': [], 'sell': []}), json.dumps({'inds': PREV}, default=default),'']
    else:
        return [json.dumps({'buy': [], 'sell': []}), json.dumps({'inds': PREV}, default=default),'']
else:
    return [json.dumps({'buy': [], 'sell': []}), json.dumps({'inds': PREV}, default=default),'']