"A nonexistent object was used in an `Input` of a Dash callback" with a multipage Dash app

Hello, I have a multi-page app. This app consists of 3 pages: home.py , evolprop.py , and satelites.py, structured as follows:
‘app.py’
pages(folder)
home.py
evolprop.py
satelites.py

On the evolprop.py page (named “Evolution Properties” in the navigation bar), there are 3 dropdowns, one of which I assigned the ID ‘mass-dropdown’. When the Dash application is executed, it throws an error due to this dropdown because the other two dropdowns are also on the home.py page (named “General Properties”). I’m not sure where to define “mass-dropdown” to avoid this error. I mean, in the future I want to add an extra page with several more dropdowns different from these previous ones and for each of them it will throw an error from what I see.

Let me show you the code of the pages and app.py.

app.py:

import dash
from dash import  html, dcc 
import dash_bootstrap_components as dbc
import pandas as pd

# Create the dash app
app = dash.Dash(__name__, use_pages=True, external_stylesheets=[dbc.themes.SPACELAB],suppress_callback_exceptions=True)

dr = pd.read_csv('notebooks/historias.dat',delim_whitespace=True)
merger = pd.read_csv('notebooks/mergers.dat', delim_whitespace=True)

# convert dataframe to list of dictionaries because dcc.Store
# accepts dict | list | number | string | boolean
dr = dr.to_dict('records')
merger = merger.to_dict('records')

# Define the navigation bar
navbar = dbc.NavbarSimple(
    children=[
        dbc.NavItem(dbc.NavLink("General properties", href="/")),    #Home
        dbc.NavItem(dbc.NavLink("Evolution properties", href="/evolprop")),
        dbc.NavItem(dbc.NavLink("Satelites", href="/satelites")),
    ],
    brand="Disk galaxies Dash",
    brand_href="/",
    color="dark",
    dark=True,
)

# Overall layout
app.layout = html.Div([
    navbar,  # Include the navigation bar
    dash.page_container,
    dcc.Store(id="ID-sat", data=None),
    dcc.Store(id="historias-df",data=dr),
    dcc.Store(id="mergers-df",data=merger)
])

this is home.py:

import dash
from dash import html, dcc, Input, Output, callback
import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from graficos_z import sp_str, diagrama_CM
from config_options import dict_options
import pandas as pd
import numpy as np

dash.register_page(__name__, name='General properties' ,path='/')

layout = dbc.Container(
    [
        dbc.Row(
    [
        dbc.Col(
            html.Div("Select Galaxy type:", className="dropdown-label"),
            width=2,
        ),
        dbc.Col(
            dcc.Dropdown(
                id='type-gal-dropdown',
                
                options=[
                    {'label': 'Lenticular', 'value': 'Galnow.dat'},
                    {'label': 'Spiral', 'value': 'Galnow-ESP.dat'}
                ],
                value='Galnow.dat', # Default value
            
            ),        

            width=2
        ),
        dbc.Col(
            html.Div("Select role:", className="dropdown-label"),
            width=1,
        ),
        dbc.Col(
            dcc.Dropdown(
                id='role-dropdown',
                options=[{"label": i, "value": j} for i,j in zip(dict_options['rol_gal'],dict_options['rol_gal_int'])],  # Acá debo hacer el Dict con la config
                value=0,  # Default selected year
            ),
            width=2,
        ),
        dbc.Col(
            html.Div('Select ID to Highlight:', className="dropdown-label"),
            width=2,            
        ),
        dbc.Col(
            dcc.Dropdown(
                id='ID-dropdown',
                options=[],  # Se edita segun el callback
                value=None,  # Default value
            ),
            width=2
        )
    ],
    className = "mb-4 dropdown-row"
        ),
        dbc.Row(
            [
                dbc.Col(
                    dcc.Graph(
                        id='CM-diagram',
                        style={'height': '70vh'}
                    ),
                    width=12
                ),
            ], 
            className="mb-4",
        ),

        dbc.Row(
            [
                dbc.Col(
                    dcc.Graph(
                        id='Spiral-str',
                        style={'height': '70vh'}
                    ),
                    width=11
                ),
            ], 
            className="mb-4",

        ),
    ],
    fluid=True,
)

#Define callback to update the ID-dropdown
@callback(
    Output('ID-dropdown', 'options'),
    [Input('type-gal-dropdown', 'value'),
     Input('role-dropdown', 'value'),
     Input('type-gal-dropdown', 'value')]  
)
def update_id_dropdown(tipo_galaxia, central_satelite, tipo_galaxia_previo):  
    if tipo_galaxia != tipo_galaxia_previo:
        return []
    
    df = pd.read_csv(tipo_galaxia, delim_whitespace=True)
    dff = df[df['central?'] == central_satelite]
    
    options = [{'label': str(galaxia_id), 'value': galaxia_id} for galaxia_id in dff['ids']]
    
    return options

# Callback to update the graphs when selecting a galaxy ID
@callback(
    [Output('CM-diagram', 'figure'),
     Output('Spiral-str', 'figure')],
    [Input('type-gal-dropdown', 'value'),
     Input('role-dropdown', 'value'),
     Input('ID-dropdown', 'value')]
)

and this is evolprop.py:

import dash
from dash import html, dcc, Input, Output,State, callback
import dash_bootstrap_components as dbc
from Historias_group import heatmap_history, evol_circ
from config_options import dict_options
import numpy as np
from dash.exceptions import PreventUpdate

dash.register_page(__name__,name='Evolution properties', path='/evolprop')

layout = dbc.Container(
    [
        dbc.Row(
    [
            dbc.Col(
                html.Div("Select galaxy type:", className="dropdown-label"),
                width=2,
            ),
            dbc.Col(
                dcc.Dropdown(
                    id='type-gal-dropdown',
                    
                    options=[
                        {'label': 'Lenticular', 'value': 'lenticular'},
                        {'label': 'Spiral', 'value': 'espiral'}
                    ],
                    value='lenticular', # Default value
                
                ),        

                width=2
            ),
            dbc.Col(
                html.Div("Select gaalxy role:", className="dropdown-label"),
                width=2
            ),
            dbc.Col(
                dcc.Dropdown(
                    id='role-dropdown',
                    options=[{"label": i, "value": j} for i,j in zip(dict_options['rol_gal'],dict_options['rol_gal_int'])],  # Acá debo hacer el Dict con la config
                    value='0',  # Default selected year
                ),
                width=1
            ),
            dbc.Col(
                html.Div('Select Mass regimen:', className="dropdown-label"),
                width=2            
            ),
            dbc.Col(
                dcc.Dropdown(
                    id='mass-dropdown',
                    options=[{"label": i, "value": i} for i in dict_options['regimen_masa']],  # Dict en un archivo aparte
                    value=dict_options['regimen_masa'][0],  # Default value
                ),
                width=2
            ),
        ],
        className = "mb-4 dropdown-row"
        ),
        dbc.Row(
            [
                dbc.Col(
                    dcc.Graph(
                        id='circ_coldgas',
                        style={'height': '75vh'}
                    ),
                    width=12
                ),
            ], 
            className="mb-4",
        ),

        dbc.Row(
            [
                dbc.Col(
                    dcc.Graph(
                        id='color_history_cen',
                        style={'height': '75vh'}
                    ),
                    width=6
                ),
                dbc.Col(
                    dcc.Graph(
                        id='color_history_sat',
                        style={'height':'75vh'}

                    ),
                    width=6
                ),
            ], 
            className="mb-4",

        ),
        dbc.Row(
            [
                dbc.Col(
                html.Div(id='link-container-sat',children=[]),  # Contenedor para el dcc.Link
                width=3
                ),


            ]

        ),
    ],
        
    fluid=True,
    style={'minHeight': '150vh'}
)

#Define callback to show the graph 
@callback(
    [Output('circ_coldgas', 'figure'),
     Output('color_history_cen', 'figure'),
     Output('color_history_sat', 'figure'),
     Output('ID-sat','data')],  
    [Input('type-gal-dropdown', 'value'),
     Input('role-dropdown', 'value'),
     Input('mass-dropdown', 'value')],
     #prevent_initial_call=True  
)

def update_graphs(tipo_galaxia, central_satelite, mass_regime):
    if tipo_galaxia==None or central_satelite== None or mass_regime==None:
        raise PreventUpdate
    
    figure_1 =  evol_circ(tipo_galaxia,mass_regime,central_satelite)

    figure_2, id_cen = heatmap_history(mass_regime,tipo_galaxia,0)
    figure_3, id_sat = heatmap_history(mass_regime,tipo_galaxia,1)
    
    return figure_1, figure_2,figure_3,id_sat

Sorry for the extension of the post.
Notes: - The app still works but the error arises.
- The error only arises when I am on the home.py page and not when I am on evolprop.py.

  • I don’t show you the complete code, only the most relevant parts

Hi @elioc

It would be easier to help if you could provide a complete minimal example (with some dummy data) that replicates the error.

In the meatime, you might find this post helpful

You can find lots of examples of multi-page apps here:
Be sure to check out example #7 on sharing data between callbacks and # 13 on syncing components between pages.