Quick answer: Branch the On item set handler on LocalStorage.ItemKey — each key fires its own handler. Use a global isSaving flag to dedupe overlapping save requests.

Pressing Save triggers two Save Complete UI notifications. The Set Item call ran once but On item set fired twice. Likely two event sheets both listen, or two Set Item calls happened.

Branch by Key

LocalStorage On item set:
    If LocalStorage.ItemKey = "player_save":
        UI show "Saved!"
    If LocalStorage.ItemKey = "settings":
        UI show "Settings saved"

Each branch handles its specific key. If both branches fire for one save, you have two Set Item calls hitting different keys; check your save logic for redundant writes.

Audit Set Item Calls

Search event sheets for “Set item”. List each call site. Common sources of duplicate Save:

Dedup with isSaving Flag

Global variable isSaving = false

  On player presses Save:
    If isSaving = false:
        isSaving = true
        LocalStorage Set "player_save" to serialize_state()

  LocalStorage On item set:
    isSaving = false
    show_notification(...)

Flag prevents starting a new save while one’s in flight. Handler clears flag on completion. Linear save flow without race conditions.

Use Trigger Once While True

For UI notifications inside the handler, wrap with System → Trigger Once While True to make sure even if the parent fires twice, the UI only shows once. Bandage approach; prefer fixing the duplicate source.

Verifying

Trigger save manually. Should see one notification. Print LocalStorage.ItemKey on each trigger to confirm which key fired. If two different keys fire, you have a multi-Set save flow; consolidate.

“On item set fires per Set call. Audit your call sites and dedupe with a flag if multiple paths can save concurrently.”

Central save coordinator function — all save-y events route through it. Easier to dedupe in one place than scattered Set Item calls.