Skip to content

fix(ios): Fix screenshot and view hierarchy capture failing on iOS#6491

Draft
antonis wants to merge 1 commit into
mainfrom
fix/ios-feedback-screenshot-capture
Draft

fix(ios): Fix screenshot and view hierarchy capture failing on iOS#6491
antonis wants to merge 1 commit into
mainfrom
fix/ios-feedback-screenshot-capture

Conversation

@antonis

@antonis antonis commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

Since #6380 migrated iOS screenshot/view-hierarchy capture from PrivateSentrySDKOnly to the new SentrySDK.internal hybrid API, NATIVE.captureScreenshot() (and fetchViewHierarchy()) started returning empty on iOS.

This affects three features on iOS:

  • Feedback Widget screenshot — empty result surfaces an "Error capturing screenshot" alert that overlays and blocks the submit button, so the report is never sent (this is what turned the feedback E2E flow red).
  • attachScreenshot: true — screenshots silently dropped from error events.
  • attachViewHierarchy: true — view hierarchy silently dropped from error events.

💡 Motivation and Context

The iOS feedback E2E flow (captureFlow-ios.yml) has been failing since #6380 was merged

💚 How did you test it?

CI checks, Manual

📝 Checklist

  • I added tests to verify changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.
  • No breaking changes.

🔮 Next steps

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • fix(ios): Fix screenshot and view hierarchy capture failing on iOS by antonis in #6491
  • docs: Update 8.19.0 changelog by antonis in #6498
  • chore(deps): bump fast-uri from 3.1.2 to 3.1.4 by dependabot in #6496
  • chore(deps): pin glob 10.x to ^10.5.0 (dev-only advisory) by antonis in #6489
  • chore(deps): bump brace-expansion resolutions to ^2.1.2 (dev-only advisory) by antonis in #6488
  • chore(deps): add cross-spawn ^7.0.6 resolution (dev-only advisory) by antonis in #6487
  • chore(deps): bump js-yaml resolution to ^4.3.0 (dev-only advisory) by antonis in #6486
  • chore(deps): update CLI to v3.6.1 by github-actions in #6493
  • chore(deps): update JavaScript SDK to v10.67.0 by github-actions in #6494
  • chore(deps): update JavaScript SDK to v10.66.0 by github-actions in #6471
  • chore(deps): update Maestro to v2.7.0 by github-actions in #6481
  • chore(ios): Bump iOS binary size limit to 1650 KiB by antonis in #6485
  • chore(deps): bump tar from 7.5.16 to 7.5.20 by dependabot in #6483
  • chore(deps): bump shell-quote from 1.8.4 to 1.10.0 by dependabot in #6484
  • chore(deps): bump the codeql-action group with 3 updates by dependabot in #6475
  • chore(deps): bump brace-expansion from 1.1.13 to 1.1.16 by dependabot in #6482
  • chore(deps): bump axios from 1.16.0 to 1.18.1 by dependabot in #6479
  • chore(deps): bump actions/setup-java from 5.5.0 to 5.6.0 by dependabot in #6476

🤖 This preview updates automatically when you update the PR.

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Jul 21, 2026
@sentry

sentry Bot commented Jul 21, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
Sentry RN io.sentry.reactnative.sample 8.19.0 (99) Release

⚙️ sentry-react-native Build Distribution Settings

@antonis antonis changed the title fix(ios): Fix Feedback Widget screenshot capture failing on iOS fix(ios): Fix screenshot and view hierarchy capture failing on iOS Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3840.27 ms 1207.50 ms -2632.77 ms
Size 4.98 MiB 6.55 MiB 1.57 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
b9bebee+dirty 3850.15 ms 1227.51 ms -2622.64 ms
3d377b5+dirty 1218.48 ms 1219.51 ms 1.03 ms
1a2e7e0+dirty 3842.49 ms 1220.04 ms -2622.45 ms
e5bb5f6+dirty 3826.14 ms 1212.24 ms -2613.90 ms
6acdf1d+dirty 3844.33 ms 1212.96 ms -2631.38 ms
41d6254+dirty 3845.71 ms 1224.51 ms -2621.20 ms
9210ae6+dirty 3815.93 ms 1214.14 ms -2601.79 ms
c004dae+dirty 3850.32 ms 1227.79 ms -2622.53 ms
4e0b819+dirty 3839.05 ms 1210.75 ms -2628.30 ms
0b5120f+dirty 3838.39 ms 1232.91 ms -2605.48 ms

App size

Revision Plain With Sentry Diff
b9bebee+dirty 5.15 MiB 6.68 MiB 1.53 MiB
3d377b5+dirty 3.38 MiB 4.76 MiB 1.38 MiB
1a2e7e0+dirty 4.98 MiB 6.46 MiB 1.49 MiB
e5bb5f6+dirty 4.98 MiB 6.51 MiB 1.53 MiB
6acdf1d+dirty 4.98 MiB 6.51 MiB 1.53 MiB
41d6254+dirty 5.15 MiB 6.70 MiB 1.54 MiB
9210ae6+dirty 5.15 MiB 6.68 MiB 1.53 MiB
c004dae+dirty 5.15 MiB 6.67 MiB 1.51 MiB
4e0b819+dirty 4.98 MiB 6.46 MiB 1.49 MiB
0b5120f+dirty 5.15 MiB 6.68 MiB 1.53 MiB

Previous results on branch: fix/ios-feedback-screenshot-capture

Startup times

Revision Plain With Sentry Diff
5d33fdc+dirty 3863.38 ms 1237.41 ms -2625.96 ms

App size

Revision Plain With Sentry Diff
5d33fdc+dirty 4.98 MiB 6.55 MiB 1.57 MiB

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3855.06 ms 1240.10 ms -2614.96 ms
Size 4.98 MiB 6.55 MiB 1.57 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
b0d3373+dirty 3842.49 ms 1218.49 ms -2624.00 ms
ef27341+dirty 3835.20 ms 1212.23 ms -2622.97 ms
e5bb5f6+dirty 3825.74 ms 1217.30 ms -2608.43 ms
44c8b3f+dirty 3849.24 ms 1209.94 ms -2639.31 ms
68672fc+dirty 3832.22 ms 1228.29 ms -2603.93 ms
5748023+dirty 3844.74 ms 1225.49 ms -2619.26 ms
6acdf1d+dirty 3835.35 ms 1218.30 ms -2617.06 ms
2c735cc+dirty 1223.33 ms 1224.38 ms 1.04 ms
100ce80+dirty 3843.57 ms 1226.46 ms -2617.12 ms
9210ae6+dirty 3834.11 ms 1216.64 ms -2617.47 ms

App size

Revision Plain With Sentry Diff
b0d3373+dirty 5.15 MiB 6.68 MiB 1.53 MiB
ef27341+dirty 5.15 MiB 6.68 MiB 1.53 MiB
e5bb5f6+dirty 4.98 MiB 6.51 MiB 1.53 MiB
44c8b3f+dirty 5.15 MiB 6.66 MiB 1.51 MiB
68672fc+dirty 5.15 MiB 6.71 MiB 1.55 MiB
5748023+dirty 5.15 MiB 6.68 MiB 1.53 MiB
6acdf1d+dirty 4.98 MiB 6.51 MiB 1.53 MiB
2c735cc+dirty 3.38 MiB 4.74 MiB 1.35 MiB
100ce80+dirty 5.15 MiB 6.67 MiB 1.51 MiB
9210ae6+dirty 5.15 MiB 6.68 MiB 1.53 MiB

Previous results on branch: fix/ios-feedback-screenshot-capture

Startup times

Revision Plain With Sentry Diff
5d33fdc+dirty 3831.19 ms 1208.00 ms -2623.19 ms

App size

Revision Plain With Sentry Diff
5d33fdc+dirty 4.98 MiB 6.55 MiB 1.57 MiB

Comment thread packages/core/ios/RNSentryInternal.swift Outdated
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 430.17 ms 487.53 ms 57.37 ms
Size 49.74 MiB 55.36 MiB 5.61 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
f3215d3+dirty 411.11 ms 454.38 ms 43.27 ms
d2eadf8+dirty 414.64 ms 454.56 ms 39.92 ms
b0d3373+dirty 557.66 ms 579.42 ms 21.76 ms
27d9693+dirty 419.08 ms 469.12 ms 50.04 ms
4e0b819+dirty 420.56 ms 470.08 ms 49.52 ms
9474ead+dirty 411.45 ms 446.80 ms 35.35 ms
0bd8916+dirty 412.77 ms 451.31 ms 38.54 ms
f9c1ed4+dirty 431.00 ms 466.22 ms 35.22 ms
3d536d1+dirty 524.34 ms 547.32 ms 22.98 ms
04207c4+dirty 459.19 ms 518.54 ms 59.35 ms

App size

Revision Plain With Sentry Diff
f3215d3+dirty 48.30 MiB 53.49 MiB 5.19 MiB
d2eadf8+dirty 48.30 MiB 53.48 MiB 5.18 MiB
b0d3373+dirty 48.30 MiB 53.58 MiB 5.28 MiB
27d9693+dirty 49.74 MiB 55.09 MiB 5.34 MiB
4e0b819+dirty 49.74 MiB 54.81 MiB 5.07 MiB
9474ead+dirty 48.30 MiB 53.61 MiB 5.30 MiB
0bd8916+dirty 48.30 MiB 53.57 MiB 5.26 MiB
f9c1ed4+dirty 49.74 MiB 54.86 MiB 5.12 MiB
3d536d1+dirty 49.74 MiB 55.26 MiB 5.52 MiB
04207c4+dirty 43.75 MiB 48.12 MiB 4.37 MiB

Previous results on branch: fix/ios-feedback-screenshot-capture

Startup times

Revision Plain With Sentry Diff
5d33fdc+dirty 536.16 ms 551.90 ms 15.74 ms

App size

Revision Plain With Sentry Diff
5d33fdc+dirty 49.74 MiB 55.36 MiB 5.61 MiB

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 424.49 ms 472.80 ms 48.31 ms
Size 49.74 MiB 55.36 MiB 5.61 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
a50b33d+dirty 353.21 ms 398.48 ms 45.27 ms
d038a14+dirty 405.08 ms 444.36 ms 39.28 ms
68672fc+dirty 407.55 ms 442.96 ms 35.41 ms
ad66da3+dirty 411.49 ms 449.38 ms 37.89 ms
f170ec3+dirty 505.96 ms 551.88 ms 45.92 ms
27d9693+dirty 438.63 ms 514.08 ms 75.46 ms
41d6254+dirty 406.20 ms 445.52 ms 39.32 ms
68ae91b+dirty 515.04 ms 578.08 ms 63.04 ms
5ee78d6+dirty 411.18 ms 437.83 ms 26.65 ms
ae37560+dirty 428.96 ms 456.86 ms 27.90 ms

App size

Revision Plain With Sentry Diff
a50b33d+dirty 43.94 MiB 48.94 MiB 5.00 MiB
d038a14+dirty 48.30 MiB 53.49 MiB 5.19 MiB
68672fc+dirty 48.30 MiB 53.61 MiB 5.31 MiB
ad66da3+dirty 48.30 MiB 53.49 MiB 5.19 MiB
f170ec3+dirty 48.30 MiB 53.57 MiB 5.26 MiB
27d9693+dirty 49.74 MiB 55.09 MiB 5.34 MiB
41d6254+dirty 48.30 MiB 53.60 MiB 5.30 MiB
68ae91b+dirty 49.74 MiB 54.79 MiB 5.05 MiB
5ee78d6+dirty 48.30 MiB 53.58 MiB 5.28 MiB
ae37560+dirty 48.30 MiB 53.60 MiB 5.29 MiB

Previous results on branch: fix/ios-feedback-screenshot-capture

Startup times

Revision Plain With Sentry Diff
5d33fdc+dirty 423.39 ms 506.88 ms 83.49 ms

App size

Revision Plain With Sentry Diff
5d33fdc+dirty 49.74 MiB 55.36 MiB 5.61 MiB

…nternal (#6380)"

This reverts #6380 (eae9020), restoring the pre-8.19.0 iOS native behavior.

#6380 made RNSentry access SentrySDK.internal before SentrySDK.start (during
init, from RNSentryStart and from JS integrations calling native methods like
fetchNativeAppStart/fetchNativeSdkInfo). Constructing SentrySDK.internal eagerly
reads SentryDependencyContainer.screenshotSource — a lazy var that returns and
permanently caches nil while startOptions is unset — breaking all iOS screenshot
capture (Feedback Widget screenshot, attachScreenshot, Sentry.captureScreenshot).

A targeted RN-side revert is unreliable (any pre-start SentrySDK.internal access
poisons the lazy var, and JS controls the timing), so revert the whole migration
as the interim fix. The migration can be re-landed once the underlying sentry-cocoa
issue is fixed (screenshotSource should not permanently cache nil).

Fixes #6497.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@antonis
antonis force-pushed the fix/ios-feedback-screenshot-capture branch from d8e4ead to 62591e4 Compare July 22, 2026 09:49

@antonis antonis left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified that the CI is 🟢 and tested manually that screenshots are attached to eventsd https://sentry-sdks.sentry.io/issues/5005282269/events/a7b327b1ba934e22bb1d79a7ec66fd53/

Marking as blocked till we agree on the best solution for this.

// to resolve it, breaking `RNSentryTimeToDisplayTests.swift` with
// `Undefined symbol: _TIME_TO_DISPLAY_ENTRIES_MAX_SIZE` at link time.
extern const int TIME_TO_DISPLAY_ENTRIES_MAX_SIZE;
static const int TIME_TO_DISPLAY_ENTRIES_MAX_SIZE = 50;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverting to static const reintroduces Swift link-time undefined symbol

Swift tests still reference TIME_TO_DISPLAY_ENTRIES_MAX_SIZE, but static const gives the constant internal linkage so Swift cannot resolve the external symbol at link time. Keep extern linkage or update the tests.

Evidence
  • RNSentryTimeToDisplayTests.swift uses TIME_TO_DISPLAY_ENTRIES_MAX_SIZE at lines 19 and 57.
  • The removed comment explicitly documented that static const causes Undefined symbol: _TIME_TO_DISPLAY_ENTRIES_MAX_SIZE at link time because it lacks external linkage.
  • This test file is not modified in the PR, so it still expects the externally-visible symbol.

Identified by Warden code-review · 76B-VYK

resolve(nil);
return;
}
NSData *rawViewHierarchy = [PrivateSentrySDKOnly captureViewHierarchy];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetchViewHierarchy nil failure propagation removed

Removing the nil check means view hierarchy capture failures return an empty array instead of nil, masking errors as successful empty attachments.

Evidence
  • The removed comment explicitly states that [] is treated as a successful empty attachment, while nil propagates capture failure to the JS layer.
  • [PrivateSentrySDKOnly captureViewHierarchy] can return nil when capture fails.
  • When rawViewHierarchy is nil, arrayWithCapacity:0 creates an empty array, the for-loop is skipped, and resolve(viewHierarchy) returns [] instead of nil.
  • This silently drops view hierarchy capture failures, breaking the error-handling contract with JavaScript.

Identified by Warden find-bugs · 92V-WR6

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

Labels

Blocked ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant