Strange button and checkbox behaviour - inconsistent checkbox and session values

Good to be here :slight_smile: - 2 weeks of Streamlit so it is probably me, not the Streamlit :-).
But what am I doing wrong or how to fix it :-)? Thanks in advance.
Problem explained in the code.

macOS, latest local Streamlit, Python 3.11.5

import streamlit as st
from pathlib import Path

PAGE_NAME = "CHAT"

def main():
    if PAGE_NAME not in st.session_state:
        print(PAGE_NAME, "not in session state")
        st.session_state[PAGE_NAME] = {
            'files': {}
        }
        for n in range(1, 6):
            st.session_state[PAGE_NAME]['files'][f'file_{n}.txt'] = {
                'content': f'Hello world {n}',
                'checked': False
            }
    session = st.session_state[PAGE_NAME]
    sb = st.sidebar

    st.markdown("""
Unexpected behaviour
- click the checkbox in the first row and click 'Remove selected'
- first of remaining rows becomes checked (but it should not to be)
- session json shows inconsistency for 'checked' value (it says False)

refresh / reload the page (F5)

Workaround
- click the checkbutton in the first row and click '(workaround)' button that does nothing (except of reload or whatever fixes it :-))
- click 'Remove selected' button - now first row disappears but none of remaining checkboxes will checked
- session json shows proper checbox states

## WHY?
## How to fix it (what to puyt after removing session states?)

""")

    if sb.button("Remove selected", key="chat_remove_checked", use_container_width=True):
        session['files'] = {k: v for k, v in session['files'].items() if not v['checked']}

    if sb.button("(workaround)", key="chat_remove_checked2", use_container_width=True):
        pass

    for n, (filename, content) in enumerate(session['files'].items()):
        col1, col2 = st.columns(2)
        session['files'][filename]['checked'] = col1.checkbox(f"chat_files_{n-5}", key=f"chat_files_{n}", value=content['checked'])
        col2.write(content['content'])

    st.json(session['files'], expanded=True)

if __name__ == "__main__":
    main()
1 Like