Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RCTImageView / RCTImageLoader crash #9849

Closed
barbarNik opened this issue Sep 12, 2016 · 35 comments
Closed

RCTImageView / RCTImageLoader crash #9849

barbarNik opened this issue Sep 12, 2016 · 35 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@barbarNik
Copy link

Issue Description

Few days ago we've release our application to AppStore and stared to receive quite a significant amount of crashes on Crashlytic related to RCTImageView, this is few of the crashes we getting, i can attach more if it is required:

Crashed: com.apple.NSURLSession-work
Crashed: com.apple.main-thread
0  libsystem_platform.dylib       0x181ad2888 OSAtomicOr32Barrier + 34
1  AppMobile                    0x1002ec2d0 __102-[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:progressBlock:completionBlock:]_block_invoke.253 + 4297802448
2  AppMobile                    0x1002eec8c -[RCTImageView cancelImageLoad] + 4297813132
3  AppMobile                    0x1002ef06c -[RCTImageView reloadImage] + 4297814124
4  AppMobile                    0x1002eff70 -[RCTImageView didMoveToWindow] + 4297817968
5  UIKit                          0x186fd3ac8 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1556
6  UIKit                          0x18738e428 -[UIImageView _didMoveFromWindow:toWindow:] + 80
7  UIKit                          0x186fd37ac -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
8  UIKit                          0x186fd37ac -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
9  UIKit                          0x186fd37ac -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
10 UIKit                          0x186fd2d40 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 152
11 Foundation                     0x1827a8cc0 -[NSISEngine withBehaviors:performModifications:] + 168
12 UIKit                          0x186fd2bc4 -[UIView(Hierarchy) _postMovedFromSuperview:] + 532
13 UIKit                          0x186fe0678 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1784
14 AppMobile                    0x1002b119c -[UIView(React) didUpdateReactSubviews] + 4297560476
15 AppMobile                    0x1002b83d0 -[RCTView didUpdateReactSubviews] + 4297589712
16 AppMobile                    0x1002cacd8 __59-[RCTShadowView processUpdatedProperties:parentProperties:]_block_invoke + 4297665752
17 AppMobile                    0x1002d8188 __77-[RCTUIManager _amendPendingUIBlocksWithStylePropagationUpdateForShadowView:]_block_invoke + 4297720200
18 AppMobile                    0x1002db7d4 __29-[RCTUIManager flushUIBlocks]_block_invoke + 4297734100
19 libdispatch.dylib              0x1818c14bc _dispatch_call_block_and_release + 24
20 libdispatch.dylib              0x1818c147c _dispatch_client_callout + 16
21 libdispatch.dylib              0x1818c6b84 _dispatch_main_queue_callback_4CF + 1844
22 CoreFoundation                 0x181e2cd50 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
23 CoreFoundation                 0x181e2abb8 __CFRunLoopRun + 1628
24 CoreFoundation                 0x181d54c50 CFRunLoopRunSpecific + 384
25 GraphicsServices               0x18363c088 GSEventRunModal + 180
26 UIKit                          0x187042088 UIApplicationMain + 204
27 AppMobile                    0x1000b3da4 main (main.m:16)
28 libdispatch.dylib              0x1818f28b8 (Missing)
Crashed: com.facebook.react.ImageLoaderURLRequestQueue
0  libobjc.A.dylib                0x182a25b90 objc_msgSend + 16
1  AppMobile                    0x100242354 __30-[RCTImageLoader dequeueTasks]_block_invoke + 4297745236
2  libdispatch.dylib              0x182df94bc _dispatch_call_block_and_release + 24
3  libdispatch.dylib              0x182df947c _dispatch_client_callout + 16
4  libdispatch.dylib              0x182e054c0 _dispatch_queue_drain + 864
5  libdispatch.dylib              0x182dfcf80 _dispatch_queue_invoke + 464
6  libdispatch.dylib              0x182df947c _dispatch_client_callout + 16
7  libdispatch.dylib              0x182e07914 _dispatch_root_queue_drain + 2140
8  libdispatch.dylib              0x182e070b0 _dispatch_worker_thread3 + 112
9  libsystem_pthread.dylib        0x183011470 _pthread_wqthread + 1092
10 libsystem_pthread.dylib        0x183011020 start_wqthread + 4

We was not able to reproduce this issue on our side yet. But we loading a lot of images in our application (up to 300), can such amount affect it somehow?
It would be great if we cat get at least a hint where is the source of the issue =)

Additional Information

  • React Native version: [0.32]
  • Platform(s) (iOS, Android, or both?): [iOS]
  • Operating System (macOS, Linux, or Windows?): [Mac]
@pavlelekic
Copy link

I'm getting similar crashes, I'm using RN 0.32.1, iOS only.
Here is the complete stacktrace
com.arbor-education.arbormobileapp_issue_26_crash_0dc799c030d240e8a58f2b882ba76d9c.txt

@gre
Copy link
Contributor

gre commented Sep 13, 2016

do you know if it still repro on 0.33 ?

@ehaas
Copy link

ehaas commented Sep 13, 2016

I am seeing a similar crash in 0.33, iPhone 6s w/ iOS 9.3.5

Stack trace:

Crashed: com.apple.main-thread
0  libsystem_platform.dylib       0x182616888 OSAtomicOr32Barrier + 34
1  irl                            0x10007df68 __102-[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:progressBlock:completionBlock:]_block_invoke (RCTImageLoader.m:502)
2  irl                            0x1000843b8 -[RCTImageView cancelImageLoad] (RCTImageView.m:190)
3  irl                            0x100085668 -[RCTImageView didMoveToWindow] (RCTImageView.m:388)
4  UIKit                          0x187b17ac8 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1556
5  UIKit                          0x187ed2428 -[UIImageView _didMoveFromWindow:toWindow:] + 80
6  UIKit                          0x187b177ac -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
7  UIKit                          0x187b177ac -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
8  UIKit                          0x187b177ac -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
9  UIKit                          0x187b16d40 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 152
10 UIKit                          0x187b16ba8 -[UIView(Hierarchy) _postMovedFromSuperview:] + 504
11 UIKit                          0x187e303b4 __UIViewWasRemovedFromSuperview + 228
12 UIKit                          0x187b155e8 -[UIView(Hierarchy) removeFromSuperview] + 424
13 irl                            0x1000dc4f8 -[RCTView react_updateClippedSubviewsWithClipRect:relativeToView:] (RCTView.m:336)
14 irl                            0x1000dc6c8 -[RCTView updateClippedSubviews] (RCTView.m:365)
15 irl                            0x1000dc728 -[RCTView layoutSubviews] (RCTView.m:379)
16 UIKit                          0x187b181e4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 656
17 QuartzCore                     0x1854a698c -[CALayer layoutSublayers] + 148
18 QuartzCore                     0x1854a15c8 CA::Layer::layout_if_needed(CA::Transaction*) + 292
19 QuartzCore                     0x1854a1488 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
20 QuartzCore                     0x1854a0ab8 CA::Context::commit_transaction(CA::Transaction*) + 252
21 QuartzCore                     0x1854a0818 CA::Transaction::commit() + 500
22 QuartzCore                     0x1854f4188 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 592
23 IOKit                          0x182c31e54 IODispatchCalloutFromCFMessage + 372
24 CoreFoundation                 0x182959030 __CFMachPortPerform + 180
25 CoreFoundation                 0x1829717d4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56
26 CoreFoundation                 0x182970f0c __CFRunLoopDoSource1 + 436
27 CoreFoundation                 0x18296ec64 __CFRunLoopRun + 1800
28 CoreFoundation                 0x182898c50 CFRunLoopRunSpecific + 384
29 GraphicsServices               0x184180088 GSEventRunModal + 180
30 UIKit                          0x187b86088 UIApplicationMain + 204
31 irl                            0x10003e3f0 main (main.m:16)
32 libdispatch.dylib              0x1824368b8 (Missing)

@littlesome
Copy link

0.33 same issue #9882

@ide ide changed the title RCTImageView crash RCTImageView / RCTImageLoader crash Sep 29, 2016
@joenoon
Copy link
Contributor

joenoon commented Oct 1, 2016

Here is a crash report with 0.34: https://gist.github.com/joenoon/107f86251db049cad2377fc8201a475a

@finalquest
Copy link

finalquest commented Oct 3, 2016

The same issue in 0.34. Crash when calling [RCTNetworkTask cancel]

@7ynk3r
Copy link

7ynk3r commented Oct 4, 2016

Same here

@jerson
Copy link

jerson commented Oct 4, 2016

same same same here :( http://crashes.to/s/c55a4e38ab1

@7ynk3r
Copy link

7ynk3r commented Oct 4, 2016

is it working on 0.31? an alternative for now might be to just downgrade.

@jmcginty
Copy link

jmcginty commented Oct 4, 2016

I am getting the same or similar error on rn 0.34. It's crashing when attempting to set cancelLoad to nil. Looks like cancelLoad may be called again while it's still cancelling.

Thread 1Queue : com.apple.main-thread (serial)
#0 0x239bc6c6 in objc_release ()
#1 0x001e3242 in 101-[RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:completionBlock:]_block_invoke.201 at /Users/james/projects/react-native/MobilePos/node_modules/react-native/Libraries/Image/RCTImageLoader.m:383
#2 0x001e445a in __102-[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:progressBlock:completionBlock:]_block_invoke at /Users/james/projects/react-native/MobilePos/node_modules/react-native/Libraries/Image/RCTImageLoader.m:500
#3 0x001e875c in -[RCTImageView cancelImageLoad] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/Libraries/Image/RCTImageView.m:189
#4 0x001ea2be in -[RCTImageView didMoveToWindow] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/Libraries/Image/RCTImageView.m:384
#5 0x2877e358 in -UIView(Internal) _didMoveFromWindow:toWindow:
#6 0x28b210ec in -UIImageView _didMoveFromWindow:toWindow:
#7 0x2877e066 in -UIView(Internal) _didMoveFromWindow:toWindow:
#8 0x2877e066 in -UIView(Internal) _didMoveFromWindow:toWindow:
#9 0x2877e066 in -UIView(Internal) _didMoveFromWindow:toWindow:
#10 0x2877d7b8 in __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke ()
#11 0x2499ddf8 in -NSISEngine withBehaviors:performModifications:
#12 0x2877d682 in -UIView(Hierarchy) _postMovedFromSuperview:
#13 0x28a87b32 in __UIViewWasRemovedFromSuperview ()
#14 0x2877c390 in -UIView(Hierarchy) removeFromSuperview
#15 0x001825b8 in -[RCTView react_updateClippedSubviewsWithClipRect:relativeToView:] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/React/Views/RCTView.m:336
#16 0x001807d6 in -[UIView(RCTViewUnmounting) react_updateClippedSubviewsWithClipRect:relativeToView:] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/React/Views/RCTView.m:49
#17 0x001807d6 in -[UIView(RCTViewUnmounting) react_updateClippedSubviewsWithClipRect:relativeToView:] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/React/Views/RCTView.m:49
#18 0x001821d2 in -[RCTView react_updateClippedSubviewsWithClipRect:relativeToView:] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/React/Views/RCTView.m:299
#19 0x0014f46a in -[RCTScrollView updateClippedSubviews] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/React/Views/RCTScrollView.m:522
#20 0x0014fe0a in -[RCTScrollView scrollViewDidScroll:] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/React/Views/RCTScrollView.m:606
#21 0x28a9d4a4 in -UIScrollView(UIScrollViewInternal) _notifyDidScroll
#22 0x287a0d5a in -UIScrollView setContentOffset:
#23 0x0014ca6c in -[RCTCustomScrollView setContentOffset:] at /Users/james/projects/react-native/MobilePos/node_modules/react-native/React/Views/RCTScrollView.m:269
#24 0x2893adfe in -UIScrollView _smoothScrollWithUpdateTime:
#25 0x26863a0a in CA::Display::DisplayLinkItem::dispatch() ()
#26 0x26863856 in CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) ()
#27 0x25f4a50a in IOMobileFramebufferVsyncNotifyFunc ()
#28 0x24458758 in IODispatchCalloutFromCFMessage ()
#29 0x241b637c in __CFMachPortPerform ()
#30 0x241ca5b2 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION
()
#31 0x241c9cc6 in __CFRunLoopDoSource1 ()
#32 0x241c80d8 in __CFRunLoopRun ()
#33 0x24117228 in CFRunLoopRunSpecific ()
#34 0x24117014 in CFRunLoopRunInMode ()
#35 0x25707ac8 in GSEventRunModal ()
#36 0x287eb188 in UIApplicationMain ()
#37 0x00106196 in main at /Users/james/projects/react-native/MobilePos/ios/MobilePos/main.m:16
#38 0x23dbf872 in start ()


/**
 * This returns either an image, or raw image data, depending on the loading
 * path taken. This is useful if you want to skip decoding, e.g. when preloading
 * the image, or retrieving metadata.
 */
- (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest *)request
                                                             size:(CGSize)size
                                                            scale:(CGFloat)scale
                                                       resizeMode:(RCTResizeMode)resizeMode
                                                    progressBlock:(RCTImageLoaderProgressBlock)progressHandler
                                                  completionBlock:(void (^)(NSError *error, id imageOrData, BOOL cacheResult, NSString *fetchDate))completionBlock
{
  {
    NSMutableURLRequest *mutableRequest = [request mutableCopy];
    [NSURLProtocol setProperty:@"RCTImageLoader"
                        forKey:@"trackingName"
                     inRequest:mutableRequest];

    // Add missing png extension
    if (request.URL.fileURL && request.URL.pathExtension.length == 0) {
      mutableRequest.URL = [NSURL fileURLWithPath:[request.URL.path stringByAppendingPathExtension:@"png"]];
    }
    request = mutableRequest;
  }

  // Find suitable image URL loader
  id<RCTImageURLLoader> loadHandler = [self imageURLLoaderForURL:request.URL];
  BOOL requiresScheduling = [loadHandler respondsToSelector:@selector(requiresScheduling)] ?
      [loadHandler requiresScheduling] : YES;

  __block volatile uint32_t cancelled = 0;
  __block dispatch_block_t cancelLoad = nil;
  void (^completionHandler)(NSError *, id, NSString *) = ^(NSError *error, id imageOrData, NSString *fetchDate) {
    cancelLoad = nil;

    BOOL cacheResult = [loadHandler respondsToSelector:@selector(shouldCacheLoadedImages)] ?
      [loadHandler shouldCacheLoadedImages] : YES;

    // If we've received an image, we should try to set it synchronously,
    // if it's data, do decoding on a background thread.
    if (RCTIsMainQueue() && ![imageOrData isKindOfClass:[UIImage class]]) {
      // Most loaders do not return on the main thread, so caller is probably not
      // expecting it, and may do expensive post-processing in the callback
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        if (!cancelled) {
          completionBlock(error, imageOrData, cacheResult, fetchDate);
        }
      });
    } else if (!cancelled) {
      completionBlock(error, imageOrData, cacheResult, fetchDate);
    }
  };

  // If the loader doesn't require scheduling we call it directly on
  // the main queue.
  if (loadHandler && !requiresScheduling) {
    return [loadHandler loadImageForURL:request.URL
                                   size:size
                                  scale:scale
                             resizeMode:resizeMode
                        progressHandler:progressHandler
                      completionHandler:^(NSError *error, UIImage *image){
                        completionHandler(error, image, nil);
                      }];
  }

  // All access to URL cache must be serialized
  if (!_URLRequestQueue) {
    [self setUp];
  }

  __weak RCTImageLoader *weakSelf = self;
  dispatch_async(_URLRequestQueue, ^{
    __typeof(self) strongSelf = weakSelf;
    if (cancelled || !strongSelf) {
      return;
    }

    if (loadHandler) {
      cancelLoad = [loadHandler loadImageForURL:request.URL
                                           size:size
                                          scale:scale
                                     resizeMode:resizeMode
                                progressHandler:progressHandler
                              completionHandler:^(NSError *error, UIImage *image) {
                                completionHandler(error, image, nil);
                              }];
    } else {
      // Use networking module to load image
      cancelLoad = [strongSelf _loadURLRequest:request
                                 progressBlock:progressHandler
                               completionBlock:completionHandler];
    }
  });

  return ^{
    if (cancelLoad) {
      cancelLoad();
      cancelLoad = nil;       <<< Thread 1: EXC_BAD_ACCESS (code=1, address=0x100)
    }
    OSAtomicOr32Barrier(1, &cancelled);
  };
}

@gre
Copy link
Contributor

gre commented Oct 5, 2016

@7kfpun yes, I think this bug don't exists in 0.31.

I was thinking another workaround could be that you disable the cancellation feature on Image, I'm not sure how to easily do this though. Have to be careful if it doesn't create other bugs/leaks.

@rumit91
Copy link

rumit91 commented Oct 5, 2016

May be related to commit 1418828?

@jmcginty
Copy link

jmcginty commented Oct 5, 2016

I think you are on to something @rumit91

@digitaldavenyc
Copy link

This error accounts for most of our crashes also

@sattaman
Copy link
Contributor

sattaman commented Oct 7, 2016

Not sure if this is related? #10274

@gre
Copy link
Contributor

gre commented Oct 7, 2016

@sattaman yes, I think there are bunch of issues raising the same problem

@gre
Copy link
Contributor

gre commented Oct 8, 2016

anyone have tried if #10280 fixes this?

@jerson
Copy link

jerson commented Oct 13, 2016

same on 0.36 RC :(

http://crashes.to/s/411f88cc2bd

@ide
Copy link
Contributor

ide commented Oct 13, 2016

We believe this crash has been fixed in master (64dd140) and will be included with 0.36.0-rc.1, which will be published in a few hours if the automated tests pass.

@ide ide closed this as completed Oct 13, 2016
@davidgruebl
Copy link

@jerson 0.35-rc-0 does not seem to contain a commit regarding this issue while one relevant commit was added to 0.35 - see the diff: 0f242a1...2519010
This was also confusing to me as the added commit was already described in the changelog while only the rc was out. We are already in production with 0.35 - I can keep you posted about errors. Everything seems to be fine so far, yet our app just has been out for a couple of hours.

@jerson
Copy link

jerson commented Oct 13, 2016

@davidgruebl it was tested on 0.36 RC yesterday http://crashes.to/s/411f88cc2bd today also tested in 0.35 and the same error :( now i will test in 0.36 RC1

@davidgruebl
Copy link

@jerson thanks a lot for the info! Do you know which was the last react native version that was not affected by this? Also is there anything specific you do to reproduce this error? We haven't been able to reproduce when internally testing but just seeing this in production crash logs.

@jerson
Copy link

jerson commented Oct 13, 2016

@davidgruebl 0.36RC1 has solved the error :D , thank you very much, the bug appeared when displaying a list of big pictures like this and slid down very fast

img_0093

@gre
Copy link
Contributor

gre commented Oct 13, 2016

@jerson I have also reproduced the bug with a similar view, infinite scroll on lot of images :)

@davidgruebl the bug start happening from 0.32 and is fixed from 0.36RC1

anyway, i'm glad it's fixed now, cheers!

@hnzlk2014
Copy link

hnzlk2014 commented Oct 18, 2016

@davidgruebl same on 0.36.0-rc.1
custom Component from https://github.com/wix/list-view-experiments
image
screen shot 2016-10-18 at 6 40 54

@gre
Copy link
Contributor

gre commented Oct 24, 2016

unfortunately it's still happening to me as well :(

@ide
Copy link
Contributor

ide commented Oct 26, 2016

Looks like this is still happening, #10433 is designated as the new issue to Subscribe to.

@Aaang
Copy link

Aaang commented Oct 31, 2016

I can confirm that the [RCTNetworkTask cancel] crash, that was introduced with 0.34.0 for us, is fixed with the 0.36.0.rc.1 update. 👍

But, I can also confirm that the [RCTImageLoader _loadImageOrDataWithURLRequest...] crash is not fixed with 0.36.rc.1, even though the crash rate got much better after upgrading to this version.

We upgraded our production app from 0.28.0 to 0.34.0 two weeks ago. After that, we experienced an enormous increase of crashes, so we decided to release a new app update with 0.36.0.rc.1 as soon as possible (hence the release candidate and not the stable version) as there were two promising commits in 0.35.0. and 0.36.0,rc.1 to fix this.

After evaluating the crash rate of this crash after a week on production, we saw that the crash rate was reduced by 88% again, so it really helped. But still, a proper fix would be amazing.

@barbarNik
Copy link
Author

Can confirm @Aaang messadge, loks like issue was resolved but [RCTImageLoader dequeueTasks]_ and [RCTImageLoader _loadImageOrDataWithURLRequest...] was not yet fixed

@XHTeng
Copy link

XHTeng commented Nov 18, 2016

0.37.0 also crash

@pvsousalima
Copy link

pvsousalima commented Nov 21, 2016

I am on 0.37.0 and it also crashes.

I am not rendering a big list of images, but I have a considerable data to be rendered on form of cards. If I slide the list too fast then the app crashes. Xcode says the exception was thrown on OSAtomicOr32Barrier(1, &cancelled);

I hope this can be solved.

I guess a way to "contour" this bug would be to limit the amount of items to be rendered? Because if I fetch less items into my list that doesn't seem to happen.

@bitfused
Copy link

bitfused commented Feb 22, 2017

Has [RCTImageLoader _loadImageOrDataWithURLRequest...] been fixed? Why is this issue closed?

@myusuf3
Copy link
Contributor

myusuf3 commented Apr 4, 2017

@IlyaRepo which version of react are you on?

@bitfused
Copy link

bitfused commented Apr 6, 2017

@myusuf3 0.34.0

@tezqa
Copy link

tezqa commented Aug 29, 2017

0.38.0 also crash

@facebook facebook locked as resolved and limited conversation to collaborators May 24, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests