Streamlit: Last Annotation Rollback After Selectbox Change or Delete Action

Environment

Python 3.11
Streamlit 1.31.1
Windows 10
Running locally

I’m not a professional developer (I’m a GIS specialist), so I may have missed some best practices.

Problem description

I’m building an image annotation interface in Streamlit to automatically map objects.
The user clicks on an image (using streamlit_image_coordinates), which adds an annotation to a JSON file with the following structure:


{
  "image.jpg": [
    {
      "uuid": "460550d2-d6ac-4e27-82a5-06d1763ede80",
      "x": 1270,
      "y": 1969,
      "label": "porte",
      "type_utilisation": "entrée",
      "cible": "cartographie",
      "angle_ajuste": 267.12
    }
  ],
  "image2.jpg": [
    {
      "uuid": "0da2f466-72be-4bc1-aecd-ff4b4d67c557",
      "x": 2378,
      "y": 1730,
      "label": "porte",
      "type_utilisation": "entrée",
      "cible": "cartographie",
      "angle_ajuste": 289.48
    }
  ]
}

Each annotation can be selected through a selectbox, and then edited or deleted. A button lets the user save all changes back to the JSON file.

Bug behavior

When I add multiple annotations in the same session, the last annotation added behaves inconsistently:
Example:

I add 5 annotations:

The first 4 work fine (edit/delete OK)
The 5th one behaves weirdly:

If I modify or delete it, it looks like it works, but when a rerun happens (any action that triggers a rerun like selecting a value in a selectbox or changing a number in a number_input) seems to re-inject the previous value.), the original version reappears.

I can even see the annotation added to the JSON… and then removed again. (when i’m not using temp file like now)

If I add a 6th annotation:

The 5th becomes stable
The 6th inherits the bug

If I refresh the page (F5), everything becomes stable and works as expected.

What I’ve tried so far
Managing everything with st.session_state
Avoiding session_state completely and working directly with a temporary JSON
Using a separate “temporary” JSON file, then writing it back to the main one
Saving on every interaction, or only via a dedicated save button
Manual UUID/flag management, unique keys, etc.

The bug persists no matter what I try: the last added annotation always gets rolled back on rerun, as if a “floating” version is being re-injected into the app state.

If anyone has faced something similar or has ideas to work around this rerun/session state/JSON write issue, I’d be grateful!