Repository navigation
[iOS] NSRangeException (NSMutableRLEArray) on Undo after pasting past a TextInput's maxLength #58918
Copy link
Copy link
Open
Labels
Component: TextInputRelated to the TextInput component.Related to the TextInput component.Needs: Triage 🔍Platform: iOSiOS applications.iOS applications.
Description
Description
pasting more than maxLength characters and tapping Undo in the keyboard shortcut bar crashes. RCTBackedTextInputDelegateAdapter -textField:shouldChangeCharactersInRange:replacementString: truncates the paste with setAttributedText: from inside UIKit’s text change, after UIKit has registered the paste on the undo stack, so Undo replays the full paste against the truncated text.
Steps to reproduce
Steps:
- iPad simulator with the on-screen keyboard.
- Focus the field and paste 1234567.
- Tap Undo.
React Native Version
0.87.1
Affected Platforms
Runtime - iOS
Output of npx @react-native-community/cli info
System:
OS: macOS 27.0
CPU: (18) arm64 Apple M5 Pro
Memory: 230.66 MB / 64.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 26.1.0
path: /Users/martin/.local/share/mise/shims/node
Yarn:
version: 1.22.22
path: /Users/martin/.local/share/mise/shims/yarn
npm:
version: 11.13.0
path: /Users/martin/.local/share/mise/shims/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.16.2
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 27.0
- iOS 27.0
- macOS 27.0
- tvOS 27.0
- visionOS 27.0
- watchOS 27.0
Android SDK:
System Images:
- android-35 | Google APIs Intel x86_64 Atom
Android NDK: Not Found
IDEs:
Android Studio: 2025.3 AI-253.32098.37.2534.15336583
Xcode:
version: 27.0/27A266a
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.19
path: /opt/homebrew/opt/openjdk@17/bin/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.2.0
wanted: 20.2.0
react:
installed: 19.2.3
wanted: 19.2.3
react-native:
installed: 0.87.1
wanted: 0.87.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
*** Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
Last Exception Backtrace:
0 CoreFoundation __exceptionPreprocess + 160
1 libobjc.A.dylib objc_exception_throw + 72
2 Foundation -[NSMutableRLEArray replaceObjectsInRange:withObject:length:] + 936
3 Foundation -[NSConcreteMutableAttributedString replaceCharactersInRange:withAttributedString:] + 192
4 UIFoundation __71-[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:]_block_invoke + 36
5 UIFoundation __NSConcreteTextStorageLockedForwarding + 64
6 UIFoundation -[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:] + 72
7 UIFoundation -[NSTextStorage coordinateEditing:] + 40
8 UIKitCore -[_UITextUndoOperationReplace _undoRedo] + 292
9 Foundation -[_NSUndoStack popAndInvoke] + 112
10 Foundation -[NSUndoManager undoNestedGroup] + 232
11 UIKit -[NSUndoManagerAccessibility__UIKit__Foundation undo] + 72
12 UIKitCore -[_UITextUndoManager undo] + 80
13 UIKitCore -[UISystemDefaultTextInputAssistantItem performSystemButtonActionForStyle:] + 824
14 UIKitCore -[UIApplication sendAction:to:from:forEvent:] + 96
15 UIKitCore -[UIBarButtonItem _triggerActionForEvent:fallbackSender:] + 208
16 TextInputUI -[TUIAssistantButtonBarView _didTapButtonBarButton:withEvent:] + 344
17 UIKitCore -[UIApplication sendAction:to:from:forEvent:] + 96
18 UIKitCore -[UIControl sendAction:to:forEvent:] + 104
19 UIKitCore -[UIControl _sendActionsForEvents:withEvent:] + 328
20 UIKitCore -[UIControl touchesEnded:withEvent:] + 428
21 UIKitCore -[UIWindow _sendTouchesForEvent:] + 1036
22 UIKitCore -[UIWindow sendEvent:] + 3428
23 UIKitCore -[UIApplication sendEvent:] + 384
24 UIKit -[UIApplicationAccessibility sendEvent:] + 100
25 UIKitCore __dispatchPreprocessedEventFromEventQueue + 1112
26 UIKitCore __processEventQueue + 4916
27 UIKitCore updateCycleEntry + 172
28 UIKitCore _UIUpdateSequenceRunNext + 120
29 UIKitCore schedulerStepScheduledMainSectionContinue + 56
30 UpdateCycle UC::DriverCore::continueProcessing() + 80
31 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
32 CoreFoundation __CFRunLoopDoSource0 + 168
33 CoreFoundation __CFRunLoopDoSources0 + 220
34 CoreFoundation __CFRunLoopRun + 760
35 CoreFoundation _CFRunLoopRunSpecificWithOptions + 496
36 GraphicsServices GSEventRunModal + 116
37 UIKitCore -[UIApplication _run] + 776
38 UIKitCore UIApplicationMain + 120
39 UIKitCore ???
40 ReproducerApp specialized static UIApplicationDelegate.main() + 28
41 ReproducerApp static AppDelegate.$main() + 28
42 ReproducerApp main + 120
43 dyld_sim start_sim + 20
44 dyld start + 6688
MANDATORY Reproducer
https://github.com/jmbriano/reproducer-react-native
Screenshots and Videos
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Component: TextInputRelated to the TextInput component.Related to the TextInput component.Needs: Triage 🔍Platform: iOSiOS applications.iOS applications.
Activity
piy-ushk commentedon Oct 7, 2026
I have investigated the issue. The crash happens because UIKit registers a typing undo action before asking the delegate via
shouldChangeCharactersInRange. When React Native clamps the text (e.g., formaxLength), it returnsNO, but UIKit doesn't clear the undo action. This leaves the undo stack with out-of-bounds ranges, which crashes when the user taps Undo. We can fix this by clearing the undo stack ([_backedTextInputView.undoManager removeAllActions]) whenever we clamp the text and programmatically setattributedText.I have prepared a fix for this in my fork here: https://github.com/piy-ushk/react-native/tree/fix-textinput-undo-crash. Happy to open a PR if the approach looks good!