My multi_select and plots disappear when i choose and ID

I am creating an app that has many apps, and I need to get better at seession state management. The problem I have is that, when i click on anything in the multiselect, the whole page disappears

def display_main():
    if 'appCache' not in st.session_state:
        st.session_state.appCache = ApplicationCache()
        st.session_state.model_status = {}
        st.session_state.run_next_msg = None
        st.session_state.run_data_expander = None
        st.session_state.next_run_msg_expander = None
        st.session_state.missing_data_expander = None

    appCache = st.session_state.appCache
    model_status = st.session_state.model_status
    run_data_expander = st.session_state.run_data_expander
    next_run_msg_expander = st.session_state.next_run_msg_expander
    missing_data_expander = st.session_state.missing_data_expander
    sideBar = st.sidebar
    with sideBar:
        sideBar_mode = option_menu("Select App", ["Model Data Checker", "Data Base monitoring App"], icons=["activity", "database"], menu_icon="cast", default_index=0)

    if sideBar_mode == "Model Data Checker":
        continuous_run = sideBar.checkbox("Continuous", value=False)
        run_button = st.sidebar.button("Run")

        if run_button or continuous_run:
            while True:

                if 'run_data_expander' in st.session_state and run_data_expander is not None:
                    run_data_expander = st.expander("Run Details", expanded=True)

                with run_data_expander:
                    df_missing_data_details = None
                    for model, id_data in appCache.pipeline.ids_availability_results.items():
                        all_data_available_for_model = True
                        missing_data_details = []

                        for id, data in id_data.items():
                            if not data[1]:  # If data is not available
                                all_data_available_for_model = False
                                last_available_date, delay = data[2], data[3]
                                    "ID": id,
                                    "Custom Name": data[0],
                                    "Last Available Date": last_available_date,
                                    "Delay": delay,
                                    "model": model

                        if model in model_status:

                        if all_data_available_for_model:
                            model_status[model] = st.empty()
                            model_status[model].success(f"{model}: All necessary data is available for next run.")
                            missing_ids_str = ', '.join([str(detail['ID']) for detail in missing_data_details])
                            model_status[model] = st.empty()
                            model_status[model].error(f"{model}: Missing IDs: {missing_ids_str}.")
                            temp_df = pd.DataFrame(missing_data_details)
                            temp_df.columns = ["ID", "Custom Name", "Last Available Date", "Delay", "model"]
                            temp_df = temp_df[["model", "ID", "Custom Name", "Last Available Date", "Delay"]]

                            if df_missing_data_details is not None:
                                df_missing_data_details = pd.concat([df_missing_data_details, temp_df], ignore_index=True)
                                df_missing_data_details = temp_df.copy()

                if "missing_data_expander" in st.session_state and missing_data_expander is not None:
                    missing_data_expander = st.empty()
                    missing_data_expander = st.expander(f"Missing Data Details")
                with missing_data_expander:
                    if df_missing_data_details is not None and not df_missing_data_details.empty:
                        st.dataframe(df_missing_data_details, hide_index=True)
                        st.warning("No missing data details.")

                if 'next_run_msg_expander' in st.session_state and next_run_msg_expander is not None:
                    next_run_msg_expander = st.empty()
                    next_run_msg_expander = st.expander("Next Run Schedule", expanded=True)
                with next_run_msg_expander:
                    next_run = schedual_next_run(appCache)

                if not continuous_run:

    elif sideBar_mode == "Data Base monitoring App":
        main_container = sideBar.container()

        # Radio buttons side by side
        radio_columns = main_container.columns(2)
        with radio_columns[0]:
            date_input_method ="Date Input Method", ["Period", "Date Range"])
        with radio_columns[1]:
            plot_mode ="Plot Method", ["Detailed", "Simplified", "Matrix"])
        if date_input_method == "Period":
            start_date = sideBar.date_input("Start Date",
            end_date = sideBar.date_input("End Date",
        elif date_input_method == "Date Range":
            end_date = sideBar.date_input("End Date",
            days_before = sideBar.number_input("Days Before", min_value=0)
            start_date = end_date - timedelta(days=days_before)

        sideBar_plot = sideBar.checkbox("Plot")
        run_button = st.sidebar.button("Run")
        if "selected_ids" not in st.session_state:
            st.session_state.selected_ids = []
            selected_ids = st.session_state.selected_ids
        if run_button:
            appCache.lookUp_holes_and_dupes(start_date = start_date, end_date = end_date, plot_mode = plot_mode)
            st.session_state.figures = appCache.figures
            figures = st.session_state.figures
            if isinstance(figures, dict):
                selected_ids = st.multiselect("Select IDs", list(appCache.pipeline.ids_dict["problem_generation_de_quarterly"].keys()))
                for key in figures.keys():

the problem I’ve talked about is in the “DB monitoring App”

Generally speaking, nesting widgets inside a button (or button output) is not going to be what you want. Buttons aren’t stateful like a checkbox. Buttons go back to False as soon as the user takes their next action.

Check out Button behavior and examples for a full explanation.