Clear multiple text area unexpected behaviour

Hi everyone,
Before everything the useful info:
Streamlit version 1.41.0
Python version 3.11
Running in a virtual environment on a local machine.

I want to clear 2 text_area by using a button callback. I did a very simple example:

import streamlit as st


def send():
    st.session_state.send_button_disabled = True

def clear():
    st.session_state.field_1 = ""
    st.session_state.field_2 = ""
    print(f"clear: field_1: {st.session_state.field_1} - field_2: {st.session_state.field_2}")


# INIT

if "index" not in st.session_state:
    st.session_state.index = 0

if "field_1" not in st.session_state:
    st.session_state.field_1 = ""

if "field_2" not in st.session_state:
    st.session_state.field_2 = ""

st.session_state.index += 1
print(f"UI = {st.session_state.index}")
# conversion cat
st.set_page_config(layout="wide")
st.header("Test")

# add container
container = st.container(border=True)

print(f"UI before: field_1: {st.session_state.field_1} - field_2: {st.session_state.field_2}")

st.session_state.field_1 = container.text_area(label="**field_1 :**", placeholder="field_1", value=st.session_state.field_1)

print(f"UI between: field_1: {st.session_state.field_1} - field_2: {st.session_state.field_2}")

st.session_state.field_2 = container.text_area(label="**field_2 :**", placeholder="field_2", value=st.session_state.field_2)

print(f"UI after: field_1: {st.session_state.field_1} - field_2: {st.session_state.field_2}")

st.button("Clear", type="primary", on_click=clear)

The behaviour of this code is unexpected and I share with you GIF:
msedge_vi4Tt1nDXv

As you can see only the first field is cleared and in a more complex code it depends of what kind of action have been done before triggering the clear button.

I provide the log of my actions with some comments:

First loading (F5)

UI = 1
UI before: field_1: - field_2:
UI between: field_1: - field_2:
UI after: field_1: - field_2:

Editing first field and click on the second one

UI = 2
UI before: field_1: - field_2:
UI between: field_1: aze - field_2:
UI after: field_1: aze - field_2:

Editing second field and click and validate the second field

UI = 3
UI before: field_1: aze - field_2:
UI between: field_1: aze - field_2:
UI after: field_1: aze - field_2: aze
clear: field_1: - field_2:

click on the clear button and call the callback

The field_2 is still set even if the value was empty

UI = 4
UI before: field_1: - field_2:
UI between: field_1: - field_2:
UI after: field_1: - field_2: aze

I noticed that only the first edited field was clear (if I start by the field_2 then the field_2 is cleared but not the field_1)
I dogged the things to understand what’s I did wrong. Maybe it’s a bug from streamlit.

Thanks for your answer,

You’re hitting a variation of the “double submit” problem, because you are changing the definition of the widget itself instead of manipulating its value directly. Use keys to directly associate a widget with its value in Session State:

import streamlit as st

if "field1" not in st.session_state:
    st.session_state.field1 = ""
if "field2" not in st.session_state:
    st.session_state.field2 = ""

def clear():
    st.session_state.field1 = ""
    st.session_state.field2 = ""

with st.container(border=True):
    st.text_area("Field 1", placeholder="Lorem ipsum 1", key="field1")
    st.text_area("Field 2", placeholder="Lorem ipsum 2", key="field2")
    st.button("Clear", on_click=clear)