In version 1.37 : st.rerun Fails When Called Inside a try-except Block,

In the new version of Streamlit (1.37), it appears that calling st.rerun inside a try-except block results in a failure. This issue can be demonstrated using a decorator as an example, where the decorator includes a try-except block and wraps a function that calls st.rerun. This behavior does not occur when st.rerun is called directly within a function without such error handling.

import streamlit as st
import logging

def error_logging_decorator(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            logging.error(f"Error in function {func.__name__}: {e}")
            st.error(f"An error occurred: {e}")
            raise e  # Re-raise the exception
    return wrapper

@error_logging_decorator
def decorated_function(): #this will fail
    if st.button("Refresh"):
        st.rerun()

def plain_function():
    if st.button("Refresh"):
        st.rerun()

Expected Behavior:

Both the decorated_function and plain_function should trigger a rerun when the “Refresh” button is pressed.

Actual Behavior:

  • decorated_function raises an exception and fails to rerun.
  • plain_function works as expected and triggers a rerun.

Logs:

2024-07-26 13:10:22,773 - admin - ERROR - Error in function decorated_function: RerunData(page_script_hash='d42b4824a51958adffc95194dcc95934', is_fragment_scoped_rerun=True)
streamlit.runtime.scriptrunner.exceptions.RerunException: RerunData(page_script_hash='d42b4824a51958adffc95194dcc95934', is_fragment_scoped_rerun=True)
1 Like

this fails even if the decorator is a Streamlit native decorator. For me it fails if rerun is called inside a fragment (which was not happening before 1.37)

A temporary solution can be using state variables. For example suppose you want to switch page when all the settings have been chosen by the user:

st.session_state.selection_done = False

@st.fragment
def handle_selection():
    do_selection()
    st.session_state.selection_done = True

handle_selection()
if st.session_state.selection_done:
    st.session_state.pop('selection_done')
    st.switch_page(some_page)

In your case, you would need to store the logs or a custom object instead of a boolean

1 Like

Tried to debug my app for hours until I found this - thank you!

According to the error message:

RerunData(page_script_hash=‘7120f849767c73a08bb9d86bf0b084bd’, is_fragment_scoped_rerun=True)

It seems to think that the rerun is a fragement scoped one, even though it isnt? Changing it to rerun(scope=“fragment”) correctfully states that using that scope is only possible within fragement reruns though.

Code:

import streamlit as st

if st.button("This rerun doesnt work"):
    try:
        st.rerun()
    except Exception as e:
        st.error(f"Error: {e}")
2 Likes

there is an ongoing discussion in the related github issue here: st.rerun Fails When Called Inside a try-except Block in version 1.37 · Issue #9155 · streamlit/streamlit · GitHub

1 Like

had also this issue

Hi! Not sure if this is related, but when I updated streamlit to version 1.37.0 I experienced a similar problem.
I use tabs and within those tabs I call st.rerun(). Since the streamlit update I get the error “Exception occurred: RerunData(page_script_hash=‘’, is_fragment_scoped_rerun=True)”, which I did not get before. Any idea? Best regards