Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

iOS : Unexpected receiver type: kotlin.native.internal.NSMutableArrayAsKMutableList, Release only #3343

Closed
alexd6631 opened this issue Sep 13, 2019 · 10 comments

Comments

@alexd6631
Copy link

Hello,

I am using Kotlin Native 1.3.50 to build a multiplatform mobile app, using cocoapods plugin.
The app runs fine in debug mode, but the following code crashes in release build :

 actual fun liveDocuments() = callbackFlow<List<KDocumentSnapshot>> {
        val continuation = mainContinuation(singleShot = false) { snapshot: FIRQuerySnapshot?, error: NSError? ->
            snapshot?.documents?.map {
                documentFromSnapshot(it as FIRQueryDocumentSnapshot)
            }?.let {
                offer(it)
            }
 <... code ommited for brevity ...>
    }

The classes are generated by cinterop and snapshot.documents is a NSArray bridged as a List<*>. It seems that any method call on this list will trigger the following RuntimeException
(I tried to replace .map by a .forEach(), and even .size() throws an error)

Uncaught Kotlin exception: kotlin.RuntimeException: Unexpected receiver type:
kotlin.native.internal.NSMutableArrayAsKMutableList
        at 0   iosApp                              0x0000000100b3f1f8 __60-[FIRQuery addSnapshotListenerInternalWithOptions:listener:]_block_invoke + 216
        at 1   iosApp                              0x0000000100b2e694 _ZZN8firebase9firestore4util8internal13DispatchAsyncEPU28objcproto17OS_dispatch_queue8NSObjectONSt3__18functionIFvvEEEEN3$_08__invokeEPv + 36
        at 2   libdispatch.dylib                   0x0000000101c00c78 _dispatch_client_callout + 16
        at 3   libdispatch.dylib   

(Rest of the trace is truncated, but irrelevant)

Tell me if you need more information.

Right now I need to force the framework in debug, even when the app is built in release, which is unfortunately the only way to publish my app right now. If you have any workaround, I'll be happy to hear it.

Thanks

@alexd6631
Copy link
Author

I did revert to Kotlin 1.3.41 and the issue is not present when building in release mode.

@olonho
Copy link
Contributor

olonho commented Sep 14, 2019

Looks like a bug in devirtualization, please provide complete reproducer and we'll fix it.

@subprogram
Copy link

It seems like I have the same issue: kotlin.RuntimeException: Unexpected receiver type: kotlin.collections.HashMap
Unfortunately, I didn't manage to make reproducer in a clean project. But I've found a solution, maybe it helps.

The cause of exception was that line:
val data = notification.userInfo as Map<String, *>

With this line the issue is not reproduced:
val data = (notification.userInfo as Map<String, *>).toMutableMap()

@petrukhnov
Copy link
Contributor

petrukhnov commented Nov 19, 2019

I was able to reproduce bug with:

        var path: String? = null
        for (bundle in NSBundle.allBundles()) {
            path = (bundle as NSBundle).pathForResource(name, null)
            if (path!= null) {
                break
            }
        }
Instances of kotlin.Error, kotlin.RuntimeException and subclasses aren't propagated from Kotlin to Objective-C/Swift.
Other exceptions can be propagated as NSError if method has or inherits @Throws annotation.
Uncaught Kotlin exception: kotlin.RuntimeException: Unexpected receiver type: kotlin.native.internal.NSMutableArrayAsKMutableList
        at 0   UIKitCore                           0x00007fff471d2a7e -[UIViewController loadViewIfRequired] + 1084
        at 1   UIKitCore                           0x00007fff47136b6c -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 160
        at 2   UIKitCore                           0x00007fff47136e6c -[UINavigationController _startTransition:fromViewController:toViewController:] + 140
        at 3   UIKitCore                           0x00007fff47137d36 -[UINavigationController _startDeferredTransitionIfNeeded:] + 868
        at 4   UIKitCore                           0x00007fff471390a1 -[UINavigationController __viewWillLayoutSubviews] + 150
        at 5   UIKitCore                           0x00007fff47119ed7 -[UILayoutContainerView layoutSubviews] + 217
        at 6   UIKitCore                           0x00007fff47d34d01 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2478
        at 7   QuartzCore                          0x00007fff2b138d41 -[CALayer layoutSublayers] + 255
        at 8   QuartzCore                          0x00007fff2b13ef33 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 517
        at 9   QuartzCore                          0x00007fff2b14a86a _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 80
        at 10  QuartzCore                          0x00007fff2b0917c8 _ZN2CA7Context18commit_transactionEPNS_11TransactionEd + 324
        at 11  QuartzCore                          0x00007fff2b0c6ad1 _ZN2CA11Transaction6commitEv + 643
        at 12  UIKitCore                           0x00007fff47867461 __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 81
        at 13  CoreFoundation                      0x00007fff23bb204c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
        at 14  CoreFoundation                      0x00007fff23bb17b8 __CFRunLoopDoBlocks + 312
        at 15  CoreFoundation                      0x00007fff23bac644 __CFRunLoopRun + 1284
        at 16  CoreFoundation                      0x00007fff23babe16 CFRunLoopRunSpecific + 438
        at 17  GraphicsServices                    0x00007fff38438bb0 GSEventRunModal + 65
        at 18  UIKitCore                           0x00007fff4784fb48 UIApplicationMain + 1621
        at 19  KhtfIosApp                          0x0000000107eae3fb main + 75
        at 20  libdyld.dylib                       0x00007fff51a1dc25 start + 1
        at 21  ???                                 0x0000000000000001 0x0 + 1

@petrukhnov
Copy link
Contributor

Workaround without exception.

val bundles = (NSBundle.allBundles()).toList()
        var path: String? = null
        for (bundle in bundles) {
            path = (bundle as NSBundle).pathForResource(name, null)
            if (path!= null) {
                break
            }
        }

@artdfel
Copy link
Contributor

artdfel commented Nov 20, 2019

Hello everyone! Thanks for those snippets, they are making a lot of sense for understanding the issue.
But, none of those reproduced the behavior in our test projects. So, if it is possible, please complement the report either with a self-sustaining repro project or step-by-step instructions over the snippet usage. The first option is always better, as far as it prevents misinterpretation. If one desires to avoid the publicity, a project can always be shared via Slack Direct Messages(I hope all of you already know about our Kotlin Slack existence).

@StefMa
Copy link
Contributor

StefMa commented Jan 9, 2020

I just wanted to say that I have a similar issue.

Uncaught Kotlin exception: kotlin.RuntimeException: Unexpected receiver type: kotlin.collections.ArrayList

Somehow the issue is in this line:

private fun getUnreadItems(): List<UnreadItems> {
    val unreadItems = runBlocking { unreadItems() } ?: return emptyList()
    return unreadItems.items.map {
        UnreadItems(
            publisher = it.origin.title,
            blogTitle = it.title,
            href = it.alternate.firstOrNull()?.href ?: ""
        )
    }
}

If I convert the items to a MutableList first, then it works on release builds as well.
Therefore:

-    return unreadItems.items.map {
+    return unreadItems.items.toMutableList().map {

I tried to create a reproducer of this issue but without success.
It requires my whole code (and no stubbing/mocking). Otherwise it will succeed... (even without the toMutableList call of course).

@artdfel I could send you my project via Slack DM. Please write me (@StefMa) or give me your name :)

@SebOh
Copy link

SebOh commented Jan 31, 2020

I have a similar probem in my project, when calling the following lines:

val paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true)
        val documentsDirectory = paths[0] as String

In debug it's not an issue, but when building for release I get the following error:

Exception kotlin.RuntimeException: Unexpected receiver type: kotlin.native.internal.NSArrayAsKList

So far the workaround is to change the first line as follows:

val paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true).toMutableList()

I'm still trying to reproduce the error in a smaller project but fail too.

@Ribesg
Copy link

Ribesg commented Feb 4, 2020

Similar issue in this code:
image
kotlin.RuntimeException: Unexpected receiver type: com.mydomain.ApiParticipationStatus
My workaround for now:
image

homuroll added a commit that referenced this issue Feb 10, 2020
homuroll added a commit that referenced this issue Feb 12, 2020
homuroll added a commit that referenced this issue Feb 12, 2020
homuroll added a commit that referenced this issue Feb 12, 2020
homuroll added a commit that referenced this issue Feb 12, 2020
@homuroll
Copy link
Contributor

Fixed in master and will be fixed in the upcoming 1.3.70 release.

knebekaizer pushed a commit that referenced this issue Feb 13, 2020
vvlevchenko pushed a commit that referenced this issue Feb 17, 2020
(cherry picked from commit d97f00f)
vvlevchenko pushed a commit that referenced this issue Feb 18, 2020
(cherry picked from commit d97f00f)
vvlevchenko pushed a commit that referenced this issue Feb 19, 2020
(cherry picked from commit d97f00f)
vvlevchenko pushed a commit that referenced this issue Feb 19, 2020
(cherry picked from commit d97f00f)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants