Skip to content

Conversation

@vdusek
Copy link
Collaborator

@vdusek vdusek commented Jan 30, 2026

Both _identify_inactive_browsers and _close_inactive_browsers methods were modifying their respective lists (_active_browsers and _inactive_browsers) while iterating over them. This is a classic bug that can cause items to be skipped or raise RuntimeError.

The fix iterates over a copy of the list (list(...)) while modifying the original, ensuring all items are properly processed.

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

Both `_identify_inactive_browsers` and `_close_inactive_browsers` methods
were modifying their respective lists (`_active_browsers` and
`_inactive_browsers`) while iterating over them. This is a classic bug
that can cause items to be skipped or raise RuntimeError.

The fix iterates over a copy of the list (`list(...)`) while modifying
the original, ensuring all items are properly processed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vdusek vdusek added t-tooling Issues with this label are in the ownership of the tooling team. adhoc Ad-hoc unplanned task added during the sprint. labels Jan 30, 2026
@vdusek vdusek self-assigned this Jan 30, 2026
@github-actions github-actions bot added this to the 133rd sprint - Tooling team milestone Jan 30, 2026
@vdusek vdusek requested a review from Pijukatel January 30, 2026 14:15
@codecov
Copy link

codecov bot commented Jan 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.48%. Comparing base (64c246b) to head (797a23c).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1703      +/-   ##
==========================================
- Coverage   92.49%   92.48%   -0.01%     
==========================================
  Files         157      157              
  Lines       10489    10489              
==========================================
- Hits         9702     9701       -1     
- Misses        787      788       +1     
Flag Coverage Δ
unit 92.48% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Pijukatel
Copy link
Collaborator

Would this ever cause any problem? I think it is no issue in the current implementation, but it could be a hidden bug if the implementation changes. Not sure if that is good enough justification for the change :-D

_identify_inactive_browsers is sync, so it will run through the iteration without anyone modifying its list.
_close_inactive_browsers is async, so it can yield in the middle of the iteration and the _identify_inactive_browsers can start changing the list. But the worst-case scenario is that it will miss some freshly added inactive_browsers, which does not matter at all, because it is a RecurringTask that runs periodically, so they will be closed in the next run anyway.

@vdusek
Copy link
Collaborator Author

vdusek commented Jan 30, 2026

The point is, when you remove an item from a list during iteration, the iterator's index doesn't adjust, and the next item will be skipped.

lst = [1, 2, 3, 4]
for x in lst:
    print(x)
    if x == 2:
        lst.remove(x)
print(lst)
$ python run.py 
1
2
4
[1, 3, 4]

See e.g. this https://stackoverflow.com/questions/1637807/modifying-list-while-iterating

So this is clearly a bug.

@Pijukatel
Copy link
Collaborator

The point is, when you remove an item from a list during iteration, the iterator's index doesn't adjust, and the next item will be skipped.
...

Sure, but that is not the case in our code. The case in our code is that an item can be added to the list during the iteration, so such an item will be missed in the current loop, but since this function runs periodically, it does not matter, as it will be handled next time the function runs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

adhoc Ad-hoc unplanned task added during the sprint. t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants