Skip to content

[Bug] deleteScenarioCaseRuns and deleteCaseRun silently skip entries due to list mutation during iteration #442

@lil-aditya

Description

@lil-aditya

Summary

deleteScenarioCaseRuns and deleteCaseRun in DataFileClass.py call list.remove() inside a for loop over the same list. This is a classic Python bug — when an element is removed mid-iteration the internal index advances past shifted items, silently skipping the next element.

In deleteScenarioCaseRuns, if a scenario ID appears in consecutive positions within a case run's Scenarios list, the second occurrence is never deleted, leaving orphaned scenario data in resData.json that cannot be removed through the UI.

When a user deletes a scenario from case runs, all occurrences of that scenario should be removed from every case run in resData.json. Currently, consecutive duplicate entries cause the second one to be silently retained.

What did you expect? (optional)

No response

How can we reproduce it?

  1. Create a model with at least one case run
  2. Add a scenario (e.g. SC_X) to a case run so that it appears in consecutive positions in the Scenarios array inside resData.json (this can happen through re-imports or manual edits)
  3. Call the /deleteScenarioCaseRuns API endpoint with scenarioId: "SC_X"
  4. Inspect resData.json — one SC_X entry will still remain

Root cause in API/Classes/Case/DataFileClass.py lines 826-829:

# BROKEN — skips next element after removal
for cs in cases:
    for sc in cs['Scenarios']:
        if sc['ScenarioId'] == scenarioId:
            cs['Scenarios'].remove(sc)

Same pattern exists in deleteCaseRun at lines 924-926:

python
for obj in self.resData['osy-cases']:
if obj['Case'] == caserunname:
self.resData['osy-cases'].remove(obj)

Environment (optional)

OS: Any (Windows/Linux/macOS)
Python: 3.10–3.12
Branch: main (post v5.5 sync)
Affected file: API/Classes/Case/DataFileClass.py

Logs or screenshots (optional)

No error is raised — the bug is silent. The list.remove() call succeeds but the iterator skips the next element due to index shifting. This can be demonstrated with pure Python:

items = ['a', 'b', 'b', 'c'] for item in items: ... if item == 'b': ... items.remove(item) items ['a', 'b', 'c'] # second 'b' was skipped!

Related issue, PR, or discussion (optional)

Related to v5.5 sync (PR #422) which changed scenario management
Fix branch ready: fix/list-mutation-during-iteration
Fix replaces .remove() with list-comprehension filtering
Includes 6 unit tests (including regression test for consecutive duplicates)

Proposed track

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions