Quick answer: Construct 3 ForEach Element loop skipping or repeating elements when you call Array.Delete inside the loop? Mutating the array during iteration shifts indices — defer mutations.

An inventory cleanup loops every item, deletes expired ones via Array.Delete. Some live items get skipped because deletion shifts subsequent indices.

Index Shift Problem

Delete shifts later indices down by one. If your loop is at index i and deletes, index i+1 becomes index i — the next iteration jumps past it.

Two-Pass Pattern

Pass 1: ForEach Element, append expired indices to a separate Array (or Dictionary). Pass 2: iterate that list in reverse, deleting from the original. Reverse order avoids shifting.

Reverse Iteration

If supported, loop from last index to first. Deletes don’t affect not-yet-visited (lower) indices.

Build Filtered Array

Even cleaner: append non-expired items to a new array; replace the original. O(N) instead of O(N²) deletions.

Verifying

Cleanup deletes exactly the items you intended — no skipped survivors, no skipped expired entries.

“Mutating during ForEach shifts indices. Two-pass or reverse-iterate.”

Build a tiny ‘remove where predicate’ helper in event sheets — one place to maintain the safe deletion pattern.