I am trying to delete objects from a list by choosing them via a multiselect widget. However, after the app reruns I get the error: streamlit.errors.StreamlitAPIException:Every Multiselect default value must exist in options
if st.button("Fill") or "options" not in st.session_state:
st.session_state.options=["a","b","c"]
def submit():
for item in st.session_state.selected:
st.session_state.options.remove(item)
form=st.form("My form")
form.multiselect("Select", st.session_state.options, key="selected")
form.form_submit_button("Submit", on_click=submit)
I tried to add the line st.session_state.selected=[]
to the submit function so that the multiselect-box is cleared and does not reference deleted items, but it did not solve the issue.
The error message looks like this:
Exception in thread ScriptRunner.scriptThread:
Traceback (most recent call last):
File "/Users/arc/opt/anaconda3/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/Users/arc/opt/anaconda3/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/Users/arc/opt/anaconda3/lib/python3.8/site-packages/streamlit/script_runner.py", line 182, in _process_request_queue
widget_states = self._session_state.as_widget_states()
File "/Users/arc/opt/anaconda3/lib/python3.8/site-packages/streamlit/state/session_state.py", line 447, in as_widget_states
return self._new_widget_state.as_widget_states()
File "/Users/arc/opt/anaconda3/lib/python3.8/site-packages/streamlit/state/session_state.py", line 198, in as_widget_states
states = [
File "/Users/arc/opt/anaconda3/lib/python3.8/site-packages/streamlit/state/session_state.py", line 201, in <listcomp>
if self.get_serialized(widget_id)
File "/Users/arc/opt/anaconda3/lib/python3.8/site-packages/streamlit/state/session_state.py", line 179, in get_serialized
serialized = metadata.serializer(item.value)
File "/Users/arc/opt/anaconda3/lib/python3.8/site-packages/streamlit/elements/multiselect.py", line 139, in serialize_multiselect
return _check_and_convert_to_indices(opt, value)
File "/Users/arc/opt/anaconda3/lib/python3.8/site-packages/streamlit/elements/multiselect.py", line 118, in _check_and_convert_to_indices
raise StreamlitAPIException(
streamlit.errors.StreamlitAPIException: Every Multiselect default value must exist in options
I am not sure what you mean. If you mean making the list options into a normal variable instead of an entry of the session_state dictionary then this doesn’t really work as the list would stay the same after pressing the submit button as the script gets run from top to bottom again. I want to be able to change the list via selecting specific entries to remove.
Additional Info:
Turns out if you delete the widget (not the options list) from the session state each time when the app is loaded I get the behavior I intend—if I select “a” and click on “submit” the options in the next iteration are only “b” and “c” and the list is changed. However, this seems to be more of a hack than a nice fix. I think this problem might be due to missing functionality/a bug in the library?
if "selected" in st.session_state:
del st.session_state.selected
Hey @arc, thanks for bringing this to our attention. I have looked into this a bit, and it is caused by the interactions of several things not being designed for this kind of use.
Before session state, arguments to widgets, and values received by widgets, were somewhat less dynamic, so our input validation did a fine job of catching problems right away. But now with state, scripts are doing a lot more interesting things we didn’t always design for.
In this case, the implementation detail that we track options in a multiselect using indices is leaking out, as the changing options argument means the indices no longer track the values correctly. Additionally, the widget argument validation is aimed towards making sure the basic use case of [select some values, and make them available as data for the rest of the app] works well, and it doesn’t try to account for the options changing.
In fact, before session state, changing the options would automatically reset the widget state as it would be seen as a new widget, and it was only with session state that keyed widgets had a sufficiently persistent identity that this could be an issue. That said, the question of how to handle the state of widgets whose arguments have changed is one we have long wanted to revisit, since there is a lot of room for making widgets try to update their state to conform to changed arguments.
The workaround of deleting the widget works because clearing the widget state prevents the old indices, which no longer mean the right thing, from sticking around and doing weird stuff.
The behavior you are currently experiencing is definitely not right, and I will open an issue for it, though it may take a bit to fix since there are so many factors in play and changing them could have big ripple effects that we will need to think through carefully.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.