Why do I get "ID not found in layout" when the ID is clearly in the layout

I have been writing this dash board with multiple page for a while now. I have just revamped one page and added a figure and now I am getting the dreaded error “ID not found in layout”

Attempting to connect a callback Output item to component:
  "fig_cpu"
but no components with that id exist in the layout.

If you are assigning callbacks to components that are
generated by other callbacks (and therefore not in the
initial layout), you can suppress this exception by setting
`suppress_callback_exceptions=True`.
This ID was used in the callback(s) for Output(s):
  fig_cpu.figure, img_cpu_ram.figure, img_cpu_dpt.figure, img_ram_dpt.figure

but clearly “fig_cpu” is in my layout

layout = html.Div(
    [
        html.H1(["CPU and RAM distributions"], style={"text-align": "center"}),
        html.Div(
            [
                html.Div("Machine status ", style={"display": "inline-block"}),
                html.Div(
                    [
                        dcc.Dropdown(
                            options=[
                                {"label": "Active only", "value": True},
                                {
                                    "label": "All (Active and deleted)",
                                    "value": False,
                                },
                            ],
                            value=True,
                            clearable=False,
                            placeholder="Select a status",
                            id="status_select",
                        )
                    ],
                    style={
                        "width": "18%",
                        "float": "centre",
                        "display": "inline-block",
                        "vertical-align": "middle",
                    },
                ),
            ],
            style={"text-align": "center"},
        ),
        html.P(
            "Note that this is a computationally intensive page and that there may be a delay displaying or adjusting the graphs."
        ),
        html.Div(
            [
                html.H5(["CPU distribution"], style={"text-align": "center"}),
                dcc.Graph(id="fig_cpu"),
            ]
        ),
        html.Div(
            [
                html.H5(["CPU vs RAM heatmap"], style={"text-align": "center"}),
                dcc.Graph(id="img_cpu_ram"),
            ]
        ),
        html.Div(
            [
                html.H5(["CPU vs Departments heatmap"], style={"text-align": "center"}),
                dcc.Graph(id="img_cpu_dpt"),
            ]
        ),
        html.Div(
            [
                html.H5(["RAM vs Departments heatmap"], style={"text-align": "center"}),
                dcc.Graph(id="img_ram_dpt"),
            ]
        ),
    ]
)


@callback(
    Output("fig_cpu", "figure"),
    Output("img_cpu_ram", "figure"),
    Output("img_cpu_dpt", "figure"),
    Output("img_ram_dpt", "figure"),
    Input("status_select", "value"),
)
def prepare_figures(status_select):
#some code
    return fig_cpu, img_cpu_ram, img_cpu_dpt, img_ram_dpt

The figure displays correctly but I cannot figure why I am getting the error. What is it that I don’t get?

Thanks,
François

Hello @fbissey,

Not sure why you are getting an error, but I just ran your layout as per the below without issue.

‘app.layout’ in place of ‘layout’ and ‘@app.callback’ in place of ‘@callback’. Not sure how you are importing the app if this is a secondary page.

However, if this is a secondary page, your app is trying to associate the callback with your current layout at initializing. You might be able to add this suppress_callback_exceptions=True at the end of your inputs to allow for the ids to be added later.

You can read more here:

import plotly.graph_objects as go
import dash
from dash import Dash, html, dcc, Input, Output

app = dash.Dash()
app.layout = html.Div(
    [
        html.H1(["CPU and RAM distributions"], style={"text-align": "center"}),
        html.Div(
            [
                html.Div("Machine status ", style={"display": "inline-block"}),
                html.Div(
                    [
                        dcc.Dropdown(
                            options=[
                                {"label": "Active only", "value": True},
                                {
                                    "label": "All (Active and deleted)",
                                    "value": False,
                                },
                            ],
                            value=True,
                            clearable=False,
                            placeholder="Select a status",
                            id="status_select",
                        )
                    ],
                    style={
                        "width": "18%",
                        "float": "centre",
                        "display": "inline-block",
                        "vertical-align": "middle",
                    },
                ),
            ],
            style={"text-align": "center"},
        ),
        html.P(
            "Note that this is a computationally intensive page and that there may be a delay displaying or adjusting the graphs."
        ),
        html.Div(
            [
                html.H5(["CPU distribution"], style={"text-align": "center"}),
                dcc.Graph(id="fig_cpu"),
            ]
        ),
        html.Div(
            [
                html.H5(["CPU vs RAM heatmap"], style={"text-align": "center"}),
                dcc.Graph(id="img_cpu_ram"),
            ]
        ),
        html.Div(
            [
                html.H5(["CPU vs Departments heatmap"], style={"text-align": "center"}),
                dcc.Graph(id="img_cpu_dpt"),
            ]
        ),
        html.Div(
            [
                html.H5(["RAM vs Departments heatmap"], style={"text-align": "center"}),
                dcc.Graph(id="img_ram_dpt"),
            ]
        ),
    ]
)


@app.callback(
    Output("fig_cpu", "figure"),
    Output("img_cpu_ram", "figure"),
    Output("img_cpu_dpt", "figure"),
    Output("img_ram_dpt", "figure"),
    Input("status_select", "value"),
)
def prepare_figures(status_select):
    fig = go.Figure()
    return [fig]*4

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

Sorry for not answering earlier. The issue seems to have now cleared as mysteriously as it appeared.
suppress_callback_exceptions=True is already the suggested solution and this is indeed a secondary page which is why app. is not there. So, maybe that’s the best thing to do.

The real annoying thing is the inconsistency. Some IDs were found without problems and only the ones just added weren’t. The app has grown to about 10 pages now and it was the only page with an issue. I also checked for possible name clashes and there were none. At the moment, I am suspecting __pycache__ files may have had a hand in that issue.

1 Like