Button / `st.session_state` bug introduced with 1.20?

It looks like st.session_state misbehaves since 1.20, at least when used together with an infinite loop.

import streamlit as st
import time

if "button" not in st.session_state:
	st.session_state["button"] = "----"
if "counter" not in st.session_state:
	st.session_state["counter"] = 0

def btn1_click():
	st.session_state["counter"] = 10
	st.session_state["button"] = "Btn1"


def btn2_click():
	st.session_state["counter"] = 20
	st.session_state["button"] = "Btn2"

cols = st.columns(3)
with cols[0]:
	st.button("Btn1", on_click=btn1_click)
with cols[1]:
	st.button("Btn2", on_click=btn2_click)
with cols[2]:
	ph = st.empty()

i = 0
while True:
	time.sleep(.1)
	
	if st.session_state["counter"] > 0:
		st.session_state["counter"] -= 1
		if st.session_state["counter"] == 0:
			st.session_state["button"] = "----"
	
	with ph.container():
		st.write(st.session_state)
	
	i+=1
	print(f"{i: 4d} button {st.session_state['button']} => counter {st.session_state['counter']}")
  1. With version 1.19 it is OK
  2. With version 1.20+ a second click on a button is not recognized anymore, and the st.session_state dictionary complains that the counter key does not exist.

Was there a features change in 1.20 to justify this behavior?

Hey @Nemecsek,

Thanks for sharing this! It does seem to behave differently with 1.20+. I’d recommend filing this as a bug ticket here so our engineering and product teams can take a look.

Already filed as a bug #6643
Thank you

1 Like

Amazing! Sharing the team’s notes from that thread for future readers of this forum post:

I was able to reproduce this behavior and confirm it.

After some investigation, I found that this is related to the fastRerun config option, which recently changed the default to true.

So the workaround for this issue would be to set the fastRerun config option in config.toml to false.

Please see more details here: Configuration - Streamlit Docs

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