Loop when oauth login fails

This occurs both running locally and deployed as a container in Amazon ECS. This is a non-public app using non-public code, sorry.

Using Streamlit 1.48.1 on Python 3.13.2, both running on Windows and in a Linux container.

We’re using Okta for auth, and when the user is permitted within Okta, it works great. However when they are not, we end up in a login loop that I can’t figure out how to break out of.

Ultra-simplified reproduction:

import streamlit as st
print(f"session state at start: {st.session_state}")
print(f"st.user at start: {st.user.to_dict()}")
if not st.user.is_logged_in:
    st.session_state['okta_attempted'] = True
    print(f"session state before st.login: {st.session_state}")
    st.login(provider="okta")
    st.stop()
else:
    st.write(f"Welcome {st.user}!")

When the user is not authorized (within Okta), we end up in a loop. Given the above example, what is printed to the console is:

session state at start: {}
st.user at start: {'is_logged_in': False}
session state before st.login: {'okta_attempted': True}
Error during authentication: access_denied. Error description: User is not assigned to the client application.
session state at start: {}
st.user at start: {'is_logged_in': False}
session state before st.login: {'okta_attempted': True}
Error during authentication: access_denied. Error description: User is not assigned to the client application.
(...repeated...)

In browser dev tools, I see it go to Okta and then back to http://localhost:8501/oauth2callback?state=<obfuscatedrandomchars>&error=access_denied&error_description=User+is+not+assigned+to+the+client+application.

It seems that the oauth2callback page is handling that, logging Error during authentication: access_denied. Error description: User is not assigned to the client application. but my code doesn’t seem to have access to that in any way (?)

Ultimately I want to recognize this situation and just pop up an error; optimally with the error and description from Okta/oauth2callback, but at a minimum just something generic like “Login failed”.

This feels similar to Expose OAuth errors during `st.login` · Issue #10160 · streamlit/streamlit · GitHub but I’m not sure its exactly the same. Any advice?