• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Instagram / IGListKit / 41728587611
99%
master: 100%

Build:
Build:
LAST BUILD BRANCH: main
DEFAULT BRANCH: master
Ran 03 Nov 2026 10:17PM UTC
Jobs 1
Files 54
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

03 Nov 2026 10:09PM UTC coverage: 98.754% (+0.002%) from 98.752%
41728587611

push

github

meta-codesync[bot]
Defer section invalidations requested from an update block after the queue was flushed

Summary:
Fixes a Threads iOS crash when opening search results (T296622780). The app aborts with an `NSInternalInconsistencyException` from `-[UICollectionViewData _existingNumberOfItemsInSection:]`:

```
-[IGListAdapter _invalidateLayoutForSectionController:completion:]
-[IGListAdapter _deferBlockBetweenBatchUpdates:]
-[IGListAdapter invalidateLayoutForSectionController:completion:]
closure #2 in BCNFeedSectionController.performSectionReload(...)
-[IGListAdapter performBatchAnimated:updates:completion:]_block_invoke
-[IGListBatchUpdateTransaction _applyDataUpdates]
```

D123728311 moved `BCNFeedSectionController`'s row re-measurement to `collectionContext.invalidateLayout(for:)` inside `performBatch`, relying on `IGListAdapter` to defer the invalidation until the batch is applied. The deferral only works while `_queuedCompletionBlocks` is non-nil, and that state is not reentrant:

1. Transaction T1 is in flight.
2. A section diff and a `performBatch` are queued for T2. Each `_enterBatchUpdates` replaces the queue.
3. T1 completes and its `_exitBatchUpdates` sets the queue to nil.
4. T2 runs the batch's update block. The queue is nil, so the invalidation runs immediately, inside `performBatchUpdates`, with the post-diff section index while `UICollectionView` still has the pre-diff sections.

On the search results page, overlapping transactions are common because feed media updates arrive while result sections are still diffing.

Changes:
- `_deferBlockBetweenBatchUpdates:` also defers while the updater is in its data update block, creating the queue if needed. The next `_exitBatchUpdates`, from the completion of the transaction that ran the block, flushes it.
- `_enterBatchUpdates` keeps an existing queue rather than replacing it. Before, a second enter dropped invalidations already queued, and their completions never ran.

Production crashes:
The same crash appear... (continued)

7 of 7 new or added lines in 1 file covered. (100.0%)

4517 of 4574 relevant lines covered (98.75%)

704.22 hits per line

Jobs
ID Job ID Ran Files Coverage
1 iOS - 41728587611.1 03 Nov 2026 10:17PM UTC 60
98.63
GitHub Action Run
Source Files on build 41728587611
  • Tree
  • List 54
  • Changed 3
  • Source Changed 0
  • Coverage Changed 3
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #41728587611
  • d782043d on github
  • Prev Build on main (#39995004437)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc