Session state is not respected when the options are not identical

In the example, Radio 1 and Radio 2 start with Option 2 as default value set via st.session_state.

When I change the valid options (via button callback),

Radio 2 retains the value while Radio 1 resets itself to the first value in the list of options.

Both the option sets will always have Option 2 as valid value.

I am trying to understnad why the difference in these bhaviors?

Issue is same with selectbox, pills etc. Just easily understandable with radio.

What am I missing.

Here is the code

import streamlit as st

options = {
    'sel1': [
        ['Option 1', 'Option 2'],
        ['Option 1', 'Option 2', 'Option 3'],
        ['Option 1', 'Option 2', 'Option 3', 'Option 4']
    ],
    'sel2': [
        ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
        ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
        ['Option 1', 'Option 2', 'Option 3', 'Option 4']
    ]
}

def showRadio(stCol, radioId):
    with stCol:
        st.metric(
            f'Radio {radioId}',
            st.radio(
                label='With different options across runs',
                options=options[f'sel{radioId}'][st.session_state.idx],
                index=0,
                key=f'radio{radioId}'
            )
        )


def updateDIdx():
    'Update the session_state.idx upon button click in callback'

    st.session_state.idx = (st.session_state.idx + 1) % 3


def showButton(stCol):
    with stCol:
        st.button('Change Options', on_click=updateDIdx)
        st.metric('Options Index: ', st.session_state.idx)


def radio():
    '''The main function'''

    st.set_page_config(page_title="Radio Example")

    # Set the session_state on first run
    if 'idx' not in st.session_state:
        st.session_state.idx = 0
    if 'radio1' not in st.session_state:
        st.session_state.radio1 = 'Option 2'
    if 'radio2' not in st.session_state:
        st.session_state.radio2 = 'Option 2'

    cols = st.columns(3)
    showRadio(cols.pop(0), 1)
    showRadio(cols.pop(0), 2)
    showButton(cols.pop(0))


if __name__ == '__main__':
    radio()

Below is the sample output

Streamlit version: 1.44.0
Python: 3.12

streamlit radio issue-2025-04-01-11-04-15

Setting the session_state.radio again even when it is present in session_state fixed the issue.

It also gives me the scope to check if the value is still valid.

However, I see a transistion from default value to the value I set when that happens.

Hope that wont effect the functionality

streamlit-selectbox-2025-04-01-16-04-46

Here is the updated code

import streamlit as st

options = {
    'sel1': [
        ['Option 1', 'Option 2'],
        ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
        ['Option 1', 'Option 2', 'Option 3', 'Option 4']
    ],
    'sel2': [
        ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
        ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
        ['Option 1', 'Option 2', 'Option 3', 'Option 4']
    ]
}

def showRadio(stCol, radioId):

    if f'radio{radioId}' not in st.session_state:
        st.session_state[f'radio{radioId}'] = 'Option 2'
    elif st.session_state[f'radio{radioId}'] in options[f'sel{radioId}'][st.session_state.idx]:
        st.session_state[f'radio{radioId}'] = st.session_state[f'radio{radioId}']

    with stCol:
        st.metric(
            f'Radio {radioId}',
            st.radio(
                label='With different options across runs',
                options=options[f'sel{radioId}'][st.session_state.idx],
                index=0,
                key=f'radio{radioId}'
            )
        )


def updateDIdx():
    'Update the session_state.idx upon button click in callback'

    st.session_state.idx = (st.session_state.idx + 1) % 3


def showButton(stCol):
    with stCol:
        st.button('Change Options', on_click=updateDIdx)
        st.metric('Options Index: ', st.session_state.idx)


def radio():
    '''The main function'''

    st.set_page_config(page_title="Radio Example")

    # Set the session_state on first run
    if 'idx' not in st.session_state:
        st.session_state.idx = 0
    if 'radio2' not in st.session_state:
        st.session_state.radio2 = 'Option 2'

    cols = st.columns(3)
    showRadio(cols.pop(0), 1)
    showRadio(cols.pop(0), 2)
    showButton(cols.pop(0))


if __name__ == '__main__':
    radio()

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.