realm-swift icon indicating copy to clipboard operation
realm-swift copied to clipboard

Crashes due to No such table exists Exception

Open Kysiek opened this issue 4 years ago • 24 comments
trafficstars

Goals

After updating the Realm version from 10.7.5 to 10.10.0 Crashlytics is reporting us following problems:

Fatal Exception: realm::NoSuchTable No such table exists Exception backtrace: 0 Realm 0x0000000104de1dcc _ZN5realm11NoSuchTableC1Ev + 52 1 Realm 0x0000000104de1f24 _ZNK5realm5Group15key2ndx_checkedENS_8TableKeyE + 224 2 Realm 0x0000000104eefb90 _ZNK5realm5Table18get_opposite_tableENS_6ColKeyE + 120 3 Realm 0x0000000104f0372c _ZN5realm5_impl11TableFriend23get_opposite_link_tableERKNS_5TableENS_6ColKeyE + 36 4 Realm 0x0000000104e55eac _ZNK5realm3Obj16get_target_tableENS_6ColKeyE + 40 5 Realm 0x0000000105033908 _ZN5realm7ResultsC2ENSt3__110shared_ptrINS_5RealmEEENS2_INS_14CollectionBaseEEENS_4util8OptionalINS_5QueryEEENS_14SortDescriptorE + 156 6 Realm 0x0000000104fdb868 _ZNK5realm12object_store10Collection10as_resultsEv + 244 7 Realm 0x0000000104c5e5f4 -[RLMFastEnumerator initWithBackingCollection:collection:classInfo:] + 204 8 Realm 0x0000000104c6f958 -[RLMManagedArray fastEnumerator] + 68 9 Realm 0x0000000104c5ed54 _Z16RLMFastEnumerateP22NSFastEnumerationStatemPU28objcproto17RLMFastEnumerable11objc_object + 76 10 libswiftFoundation.dylib 0x00000001a19c9bd0 $s10Foundation25NSFastEnumerationIteratorV4nextypSgyF + 180 11 RealmSwift 0x00000001056ff934 $s10RealmSwift11RLMIteratorV4nextxSgyF + 124 12 RealmSwift 0x00000001056d3b9c $s10RealmSwift4ListC6append9objectsInyqd___t7ElementQyd__RszSTRd__lF + 344 13 Appic 0x0000000102c67fb8 Appic + 5750712 14 Appic 0x0000000102821820 Appic + 1267744 15 libdispatch.dylib 0x000000019db78a84 DAF30062-4C85-3B92-B159-50602A0C9D97 + 10884 16 libdispatch.dylib 0x000000019db7a81c DAF30062-4C85-3B92-B159-50602A0C9D97 + 18460 17 libdispatch.dylib

Unfortunately I can not provide steps to reproduce as I am not able to receive this crash. We know from the users that this crash occurs at the realm first initialisation. There where no changes in database structure between update from 10.7.5 to 10.10.0.

Version of Realm and Tooling

Realm framework version: 10.10.0

Xcode version: 12.5.1

Dependency manager + version: Cocoapods 1.10.1

Kysiek avatar Jul 20 '21 08:07 Kysiek

I'm seeing this as well.

gbreen12 avatar Jul 20 '21 23:07 gbreen12

Here's my stack trace: terminating with uncaught exception of type realm::NoSuchTable: No such table exists Exception backtrace: 0 Air Quality 0x0000000102b8fd48 _ZN5realm4util6detail26ExceptionWithBacktraceBaseC2Ev + 48 1 Air Quality 0x0000000102bbdf2c _ZN5realm4util22ExceptionWithBacktraceISt9exceptionEC2IJEEEDpOT_ + 76 2 Air Quality 0x0000000102c904e8 _ZN5realm11NoSuchTableC2Ev + 60 3 Air Quality 0x0000000102c85e08 _ZN5realm11NoSuchTableC1Ev + 32 4 Air Quality 0x0000000102c86010 _ZNK5realm5Group15key2ndx_checkedENS_8TableKeyE + 448 5 Air Quality 0x0000000102c46b7c _ZN5realm5Group9get_tableENS_8TableKeyE + 132 6 Air Quality 0x0000000103406c7c _ZNK5realm5Table18get_opposite_tableENS_6ColKeyE + 100 7 Air Quality 0x000000010341ea84 _ZN5realm5_impl11TableFriend23get_opposite_link_tableERKNS_5TableENS_6ColKeyE + 76 8 Air Quality 0x0000000102d57100 _ZNK5realm3Obj16get_target_tableENS_6ColKeyE + 68 9 Air Quality 0x0000000102c50af0 _ZNK5realm14CollectionBase16get_target_tableEv + 80 10 Air Quality 0x0000000102e941ec _ZN5realm7ResultsC2ENSt3__110shared_ptrINS_5RealmEEENS2_INS_14CollectionBaseEEENS_4util8OptionalINS_5QueryEEENS_14SortDescriptorE + 172 11 Air Quality 0x0000000102e94530 _ZN5realm7ResultsC1ENSt3__110shared_ptrINS_5RealmEEENS2_INS_14CollectionBaseEEENS_4util8OptionalINS_5QueryEEENS_14SortDescriptorE + 32 12 Air Quality 0x0000000102d85548 _ZNK5realm12object_store10Collection10as_resultsEv + 160 13 Air Quality 0x000000010290dfc4 -[RLMFastEnumerator initWithBackingCollection:collection:classInfo:] + 352 14 Air Quality 0x00000001029394a4 _ZZ33-[RLMManagedArray fastEnumerator]ENK4$_18clEv + 100 15 Air Quality 0x0000000102935af4 _ZL15translateErrorsIZ33-[RLMManagedArray fastEnumerator]E4$_18EDaOT_ + 24 16 Air Quality 0x0000000102935ad0 -[RLMManagedArray fastEnumerator] + 36 17 Air Quality 0x000000010290ea44 _Z16RLMFastEnumerateP22NSFastEnumerationStatemPU28objcproto17RLMFastEnumerable11objc_object + 68 18 Air Quality 0x0000000102931df0 -[RLMManagedArray countByEnumeratingWithState:objects:count:] + 48 19 libswiftFoundation.dylib 0x00000001abd92bd0 $s10Foundation25NSFastEnumerationIteratorV4nextypSgyF + 180 20 Air Quality 0x00000001035f11c8 $s10RealmSwift11RLMIteratorV4nextxSgyF + 184 21 Air Quality 0x0000000102446c38 $s17MobileHelpersData12AssetStorageC03getD3IDs33_FDBDE4D84D2AA1ECA6A76BB63883B42ALL2inSaySSGAA0D5CacheO_tF + 304 22 Air Quality 0x00000001024452e4 $s17MobileHelpersData12AssetStorageC15getCachedAssets5inAnySayAA0D3DTOVGSayAA0D5CacheOG_tFSaySSGAJXEfU_ + 44 23 Air Quality 0x000000010244531c $s17MobileHelpersData10AssetCacheOSaySSGs5Error_pIgyozo_AcDsAE_pIegnrzo_TR + 32 24 Air Quality 0x0000000102445388 $s17MobileHelpersData10AssetCacheOSaySSGs5Error_pIgyozo_AcDsAE_pIegnrzo_TRTA + 28 25 libswiftCore.dylib 0x00000001ac060ec8 $sSTsE7flatMapySay7ElementQyd__Gqd__ABQzKXEKSTRd__lF + 860 26 Air Quality 0x0000000102444ec0 $s17MobileHelpersData12AssetStorageC15getCachedAssets5inAnySayAA0D3DTOVGSayAA0D5CacheOG_tF + 352 27 Air Quality 0x0000000102477898 $s17MobileHelpersData12AssetServiceC9getAssets5inAny7Combine0I9PublisherVySayAA0D5ModelVGs5NeverOGSayAA0D5CacheOG_tF + 188 28 Air Quality 0x000000010247847c $s17MobileHelpersData12AssetServiceCAA0dE8ProtocolA2aDP9getAssets5inAny7Combine0J9PublisherVySayAA0D5ModelVGs5NeverOGSayAA0D5CacheOG_tFTW + 32 29 Air Quality 0x0000000102314ff4 $s11Air_Quality29DistrictFacilityListViewModelC8resolverAC8Swinject8Resolver_p_tcfc + 684 30 Air Quality 0x0000000102303314 $s11Air_Quality15MainCoordinatorC25showAllDistrictFacilitiesyyF + 344 31 SwiftUI 0x00000001aecb02c8 AA8F15D9-1787-341A-9067-D5C0109DE7FF + 4707016 32 SwiftUI 0x00000001af015460 AA8F15D9-1787-341A-9067-D5C0109DE7FF + 8266848 33 SwiftUI 0x00000001aed4903c AA8F15D9-1787-341A-9067-D5C0109DE7FF + 5333052 34 SwiftUI 0x00000001aed49064 AA8F15D9-1787-341A-9067-D5C0109DE7FF + 5333092 35 SwiftUI 0x00000001aed4903c AA8F15D9-1787-341A-9067-D5C0109DE7FF + 5333052 36 SwiftUI 0x00000001aed31eb8 AA8F15D9-1787-341A-9067-D5C0109DE7FF + 5238456 37 SwiftUI 0x00000001aed8ddd4 AA8F15D9-1787-341A-9067-D5C0109DE7FF + 5615060 38 SwiftUI 0x00000001af24ebfc AA8F15D9-1787-341A-9067-D5C0109DE7FF + 10599420 39 SwiftUI 0x00000001af24c8c0 AA8F15D9-1787-341A-9067-D5C0109DE7FF + 10590400 40 SwiftUI 0x00000001af24d714 AA8F15D9-1787-341A-9067-D5C0109DE7FF + 10594068 41 UIKitCore 0x00000001aa88624c 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 7389772 42 UIKitCore 0x00000001aadd6270 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 12960368 43 UIKitCore 0x00000001aa87c174 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 7348596 44 UIKitCore 0x00000001aa87be50 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 7347792 45 UIKitCore 0x00000001aad8ac2c 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 12651564 46 UIKitCore 0x00000001aad646e8 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 12494568 47 UIKitCore 0x00000001aadedb60 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 13056864 48 UIKitCore 0x00000001aadf2574 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 13075828 49 UIKitCore 0x00000001aade9974 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 13039988 50 CoreFoundation 0x00000001a82d09e8 4FBDF167-161A-324C-A233-D516922C67E5 + 670184 51 CoreFoundation 0x00000001a82d08e4 4FBDF167-161A-324C-A233-D516922C67E5 + 669924 52 CoreFoundation 0x00000001a82cfbe8 4FBDF167-161A-324C-A233-D516922C67E5 + 666600 53 CoreFoundation 0x00000001a82c9bc8 4FBDF167-161A-324C-A233-D516922C67E5 + 641992 54 CoreFoundation 0x00000001a82c9360 CFRunLoopRunSpecific + 600 55 GraphicsServices 0x00000001bf907734 GSEventRunModal + 164 56 UIKitCore 0x00000001aad44584 33B02AB5-5DAF-3249-8DC6-5872DF830EC5 + 12363140 57 UIKitCore 0x00000001aad49df4 UIApplicationMain + 168 58 Air Quality 0x00000001022c6dd0 main + 68 59 libdyld.dylib 0x00000001a7f85cf8 E574A365-9878-348A-8E84-91E163CFC128 + 7416

gbreen12 avatar Jul 20 '21 23:07 gbreen12

Here's some code that will hopefully be helpful:

class AssetCacheDSO: Object {
    @Persisted(primaryKey: true) var name = ""
    
    @Persisted var assetIDs = List<String>()
}

private func getAssetIDs(in cache: AssetCache) -> [String] {
      guard let cacheObject = getCache(cache) else {
          return []
      }
      
      let assetIDs = cacheObject.assetIDs
      for assetID in assetIDs { // it always fails when trying to enumerate the assetIDs
          print(assetID)
      }
      return Array(assetIDs)
  }
  
  private func getCache(_ cache: AssetCache) -> AssetCacheDSO? {
      let caches = realm.objects(AssetCacheDSO.self)
      return caches.first(where: { $0.name == cache.cacheName })
  }

gbreen12 avatar Jul 20 '21 23:07 gbreen12

@gbreen12 can we see how MobileHelpersDataAssetStorage works and how it interacts with your SwiftUI views?

leemaguire avatar Jul 21 '21 07:07 leemaguire

@gbreen12 are you able to reproduce this consistently?

leemaguire avatar Jul 21 '21 07:07 leemaguire

@Kysiek @gbreen12 are you using realms on multiple threads and are you observing any realms / realm objects anywhere?

leemaguire avatar Jul 21 '21 08:07 leemaguire

@Kysiek @gbreen12 are you using realms on multiple threads and are you observing any realms / realm objects anywhere?

@leemaguire In my project I use instances of Realm on different threads, but on every thread I am instantiating the instance with empty initialiser. And yes, in my project I see code which is observing realm objects. Do you think it may be a cause for these crashes?

Kysiek avatar Jul 21 '21 12:07 Kysiek

@Kysiek is there any chance that you are deleting the object on a different thread when it is being read on another?

but on every thread I am instantiating the instance with empty initialiser

Can you show code explaining this?

Thanks

leemaguire avatar Jul 21 '21 12:07 leemaguire

So I can reproduce consistently but only on a client's device (iPhone 12). It works on my device just fine (iPhone Xr). Here's my AssetStorage:

import Foundation
import RealmSwift

public class AssetStorage: RealmStorage<AssetDTO> {
    public func getCachedAssets(inAny caches: [AssetCache]) -> [AssetDTO] {
        guard !caches.isEmpty else {
            return []
        }
        
        let assetIDs = Set(caches.flatMap { self.getAssetIDs(in: $0) })
        let assets = all().filter("id IN %@", assetIDs)
        
        return Array(assets.map { AssetDTO($0) })
    }
    
    public func getCachedAssets(inAll caches: [AssetCache]) -> [AssetDTO] {
        guard !caches.isEmpty else {
            return []
        }
        
        var assetIDs = getAssetIDs(in: caches.first!)
        
        for i in 1..<caches.count {
            if assetIDs.isEmpty {
                return []
            }
            
            assetIDs = assetIDs.filter { getAssetIDs(in: caches[i]).contains($0) }
        }
        
        return loadAll(filteredBy: NSPredicate(format: "id IN %@", assetIDs))
    }
    
    public func getCachedAssets(in cache: AssetCache) -> [AssetDTO] {
        guard let assetCache = getCache(cache) else {
            return []
        }
        
        let assetIDs = assetCache.assetIDs.split(separator: ",").compactMap { String($0) }
        
        return loadAll(filteredBy: NSPredicate(format: "id IN %@", assetIDs))
    }
    
    public func addCache(in cache: AssetCache, containing ids: [UUID]) {
        let assetCache = AssetCacheDSO()
        assetCache.name = cache.cacheName
        assetCache.assetIDs = (ids.map{$0.uuidString}).joined(separator: ",")
        
        try! realm.write {
            realm.add(assetCache)
        }
    }
    
    public func deleteCache(with cache: AssetCache) {
        guard let assetCache = getCache(cache) else {
            return
        }
        
        try! realm.write {
            realm.delete(assetCache)
        }
    }
    
    private func getAssetIDs(in cache: AssetCache) -> [UUID] {
        guard let cacheObject = getCache(cache) else {
            return []
        }
        
        let assetIDs = cacheObject.assetIDs.split(separator: ",")
        return Array(assetIDs.compactMap { UUID(uuidString: String($0)) })
    }
    
    private func getCache(_ cache: AssetCache) -> AssetCacheDSO? {
        let caches = realm.objects(AssetCacheDSO.self)
        return caches.first(where: { $0.name == cache.cacheName })
    }
}

It extends RealmStorage:

import Combine
import CleanroomLogger
import Foundation
import RealmSwift

open class RealmStorage<T>: _RealmStorage<T, UUID> where T: DSOConvertible {}

open class _RealmStorage<T, IDType>: StorageProtocol where T: DSOConvertible {
    private let realmProvider: RealmProvider
    public var realm: Realm {
        return realmProvider.realm
    }

    public init(_ realmProvider: RealmProvider = RealmProvider.shared) {
        self.realmProvider = realmProvider
    }
    
    open func observeAll(filteredBy filter: NSPredicate?, distinctByKeyPaths distinct: [String]?, sortedBy sort: [StorageSort]?) -> AnyPublisher<([T], StorageChanges), Never> {
        var allItems = all()

        if let filter = filter {
            allItems = allItems.filter(filter)
        }

        if let distinct = distinct {
            allItems = allItems.distinct(by: distinct)
        }

        if let sort = sort?.map({ SortDescriptor(keyPath: $0.keyPath, ascending: $0.ascending) }) {
            allItems = allItems.sorted(by: sort)
        }
        
        let passthroughSubject = PassthroughSubject<([T], StorageChanges), Never>()
        let token = allItems.observe { (changes) in
            switch changes {
            case .update(let values, deletions: let deletions, insertions: let insertions, modifications: let modifications):
                passthroughSubject.send((values.map { T($0) }, StorageChanges(deletions: deletions, insertions: insertions, modifications: modifications)))
            default:
                break
            }
        }
        
        return passthroughSubject.handleEvents(receiveCancel: {
            token.invalidate()
        }).eraseToAnyPublisher()        
    }

    open func loadAll() -> [T] {
        return all().map { T($0) }
    }

    open func loadAll(filteredBy filter: NSPredicate? = nil, distinctByKeyPaths distinct: [String]? = nil, sortedBy sort: [StorageSort]? = nil, paginatedBy pagination: StoragePagination? = nil) -> [T] {
        var allItems = all()

        if let filter = filter {
            allItems = allItems.filter(filter)
        }

        if let distinct = distinct {
            allItems = allItems.distinct(by: distinct)
        }

        if let sort = sort?.map({ SortDescriptor(keyPath: $0.keyPath, ascending: $0.ascending) }) {
            allItems = allItems.sorted(by: sort)
        }

        if let pagination = pagination {
            let skip = pagination.skip ?? 0
            var results: [T] = []

            if skip < allItems.count {
                var upperLimit = allItems.count - skip
                if let take = pagination.take {
                    upperLimit = min(skip + take, upperLimit)
                }

                if skip < upperLimit {
                    results = Array(allItems[skip..<upperLimit].map { T($0) })
                }
            }

            return results
        } else {
            return allItems.map { T($0) }
        }
    }

    open func load(_ key: IDType) -> T? {
        guard let dso = realm.object(ofType: T.DSO.self, forPrimaryKey: key) else {
            return nil
        }

        return T(dso)
    }
    
    open func dataExists(filteredBy filter: NSPredicate?) -> Bool {
        var allItems = all()
        
        if let filter = filter {
            allItems = allItems.filter(filter)
        }
        
        return !allItems.isEmpty
    }

    open func saveAll(_ items: [T]) {
        try! realm.write {
            let dsos = items.map { $0.toDSO() }
            realm.add(dsos, update: .modified)
            Log.verbose?.message("Saving \(items.count) \(T.self)s")
        }
    }

    open func save(_ item: T) {
        do {
            try realm.write {
                realm.add(item.toDSO(), update: .all)
            }

            Log.verbose?.message("Successful \(#function) \(T.self) to Realm")
        } catch {
            Log.error?.message("Failed \(#function) \(T.self) to Realm: \(error)")
        }
    }

    open func deleteAll() {
        let objects = all()
        try? realm.write {
            realm.delete(objects)
        }
    }

    open func deleteAll(with filter: NSPredicate) {
        let objects = all().filter(filter)
        try? realm.write {
            realm.delete(objects)
        }
    }

    open func delete(_ key: IDType) {
        guard let first = realm.object(ofType: T.DSO.self, forPrimaryKey: key) else {
            Log.error?.message("Could not find object \(T.self) with key \(key)")
            return
        }

        do {
            try realm.write {
                realm.delete(first)
            }

            Log.verbose?.message("Successful \(#function) \(T.self) to Realm")
        } catch {
            Log.error?.message("Failed \(#function) \(T.self) to Realm: \(error)")
        }
    }

    public func all() -> Results<T.DSO> {
        return realm.objects(T.DSO.self)
    }
}

I'm not watching anything and I don't think it's having any threading issues because I basically immediately change my DSO (realm object) to a DTO as soon as it comes out of the storage class.

gbreen12 avatar Jul 21 '21 15:07 gbreen12

@gbreen12 are you able to get the clients realm file and use it from your device to see if the crash can be reproduced locally?

leemaguire avatar Jul 21 '21 15:07 leemaguire

How can I get the realm file from their phone?

gbreen12 avatar Jul 21 '21 15:07 gbreen12

@gbreen12 do you have access to their phone? If so you could grab it by doing what's described here https://developer.apple.com/forums/thread/21660

leemaguire avatar Jul 21 '21 15:07 leemaguire

Can you show me how you do the DSO DTO conversion? observeAll. Is RealmStorage used across multiple threads?

leemaguire avatar Jul 21 '21 15:07 leemaguire

You know what, I lied. This particular case doesn't use a DTO. I just get that cache DSO and then attempt to get the string list.

gbreen12 avatar Jul 21 '21 19:07 gbreen12

Unfortunately I can't get the realm file because it's in a shared folder and I've already updated the code to use a comma separated string over a list of strings and he has updated the app.

gbreen12 avatar Jul 21 '21 19:07 gbreen12

Ok, just for further reference know that accessing a object after you have deleted it should hit NoSuchTable. Although we have checks in place to prevent this, if you time it really specifically from a multi thread / process scenario there is a chance you can bypass the checks in the Cocoa layer and hit this exception in our Core layer.

leemaguire avatar Jul 22 '21 07:07 leemaguire

@gbreen12 Is that device still hitting the crash consistently?

ejm01 avatar Sep 07 '21 21:09 ejm01

No I had to implement a work around and had that use update. Sorry

gbreen12 avatar Sep 09 '21 22:09 gbreen12

This happened again on another app on another device. Here is the full stack trace:

Asset Info realm::Group::key2ndx_checked(realm::TableKey) const
Asset Info realm::Table::get_opposite_table(realm::ColKey) const
Asset Info realm::_impl::TableFriend::get_opposite_link_table(realm::Table const&, realm::ColKey)
Asset Info realm::Obj::get_target_table(realm::ColKey) const
Asset Info realm::Results::Results(std::__1::shared_ptr<realm::Realm>, std::__1::shared_ptr<realm::CollectionBase>, realm::util::Optional<realm::Query>, realm::SortDescriptor)
Asset Info realm::object_store::Collection::as_results() const
Asset Info -[RLMFastEnumerator initWithBackingCollection:collection:classInfo:]
Asset Info -[RLMManagedArray fastEnumerator]
Asset Info RLMFastEnumerate(NSFastEnumerationState*, unsigned long, id<RLMFastEnumerable>)
libswiftFoundation.dylib Foundation.NSFastEnumerationIterator.next() -> Any?
Asset Info RealmSwift.RLMIterator.next() -> A?
Asset Info generic specialization <RealmSwift.List<Swift.String>> of (extension in Swift):Swift.Sequence._copyContents(initializing: Swift.UnsafeMutableBufferPointer<A.Element>) -> (A.Iterator, Swift.Int)
Asset Info merged MobileHelpersData.EsriTilePackDSO.availableApps.getter : [Swift.String]
Asset Info MobileHelpersData.SystemUserDTO.init(MobileHelpersData.SystemUserDSO) -> MobileHelpersData.SystemUserDTO
Asset Info MobileHelpersData._RealmStorage.load(B) -> A?
Asset Info MobileHelpersData.UserService.currentUserIsInRole(Swift.String) -> Swift.Bool
Asset Info protocol witness for MobileHelpersData.UserServiceProtocol.currentUserIsInRole(Swift.String) -> Swift.Bool in conformance MobileHelpersData.UserService : MobileHelpersData.UserServiceProtocol in MobileHelpersData
Asset Info Asset_Info.MainCoordinator.getMediaViewModel(asset: MobileHelpersData.AssetModel) -> MobileHelpersShared.SharedMediaViewModel MainCoordinator.swift:284
Asset Info Asset_Info.MainCoordinator.showAssetDetails(asset: MobileHelpersData.AssetModel) -> () MainCoordinator.swift:255
Asset Info merged partial apply forwarder for closure #1 (MobileHelpersData.AssetModel) -> () in Asset_Info.MainCoordinator.showAssetPicker(coordinator: MobileHelpersShared.SharedAssetPickerCoordinator) -> ()
Asset Info partial apply forwarder for reabstraction thunk helper from @escaping @callee_guaranteed (@guaranteed MobileHelpersData.AssetModel) -> () to @escaping @callee_guaranteed (@in_guaranteed MobileHelpersData.AssetModel) -> () <compiler-generated>:0
Combine  Combine.Subscribers.Sink.receive(A) -> Combine.Subscribers.Demand
Combine  protocol witness for Combine.Subscriber.receive(A.Input) -> Combine.Subscribers.Demand in conformance Combine.Subscribers.Sink<A, B> : Combine.Subscriber in Combine 
Combine  Combine.PassthroughSubject.Conduit.offer(A) -> ()
Combine  partial apply forwarder for closure #1 (Combine.ConduitBase<A, B>) -> () in Combine.PassthroughSubject.send(A) -> ()
Combine  Combine.ConduitList.forEach((Combine.ConduitBase<A, B>) throws -> ()) throws -> ()
Combine  Combine.PassthroughSubject.send(A) -> ()
Asset Info closure #1 (MobileHelpersData.AssetModel) -> () in MobileHelpersShared.SharedAssetPickerCoordinator.(getViewController in _4BDF4463BCC232C2A85DA0ABD9ADC497)(parent: MobileHelpersData.AssetModel?, scrollToAssetID: Foundation.UUID?) -> __C.UIViewController
Asset Info partial apply forwarder for reabstraction thunk helper from @escaping @callee_guaranteed (@guaranteed MobileHelpersData.AssetModel) -> () to @escaping @callee_guaranteed (@in_guaranteed MobileHelpersData.AssetModel) -> ()
Combine  Combine.Subscribers.Sink.receive(A) -> Combine.Subscribers.Demand
Combine  protocol witness for Combine.Subscriber.receive(A.Input) -> Combine.Subscribers.Demand in conformance Combine.Subscribers.Sink<A, B> : Combine.Subscriber in Combine  Combine  Combine.PassthroughSubject.Conduit.offer(A) -> ()
Combine  partial apply forwarder for closure #1 (Combine.ConduitBase<A, B>) -> () in Combine.PassthroughSubject.send(A) -> ()
Combine  Combine.ConduitList.forEach((Combine.ConduitBase<A, B>) throws -> ()) throws -> ()
Combine  Combine.PassthroughSubject.send(A) -> ()
Asset Info partial apply forwarder for closure #3 () -> () in closure #1 (MobileHelpersData.AssetModel) -> <<opaque return type of (extension in SwiftUI):SwiftUI.View.id<A where A1: Swift.Hashable>(A1) -> some>>.0 in closure #1 () -> SwiftUI.ForEach<[MobileHelpersData.AssetModel], Foundation.UUID, <<opaque return type of (extension in SwiftUI):SwiftUI.View.id<A where A1: Swift.Hashable>(A1) -> some>>.0> in closure #1 (SwiftUI.ScrollViewProxy) -> <<opaque return type of (extension in SwiftUI):SwiftUI.View.onAppear(perform: () -> ()?) -> some>>.0 in MobileHelpersShared.SharedAssetPickerView.body.getter : some
SwiftUI partial apply forwarder for implicit closure #2 () -> () in implicit closure #1 (SwiftUI.PrimitiveButtonStyleConfiguration) -> () -> () in SwiftUI.DefaultListButtonStyle.ListButton.body.getter : some
SwiftUI reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_guaranteed () -> (@out ())
SwiftUI function signature specialization <Arg[0] = Value Promoted from Box> of closure #2 () -> () in SwiftUI.PlatformItemList.containerSelectionBehavior.getter : SwiftUI.PlatformItemList.Item.SelectionBehavior?
SwiftUI SwiftUI.UITableViewListCoordinator.tableView(_: __C.UITableView, didSelectRowAt: Foundation.IndexPath) -> ()
SwiftUI merged @objc SwiftUI.UITableViewListCoordinator.tableView(_: __C.UITableView, didSelectRowAt: Foundation.IndexPath) -> ()
UIKitCore -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:isCellMultiSelect:deselectPrevious:]
UIKitCore -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:]
UIKitCore -[UITableView _userSelectRowAtPendingSelectionIndexPath:]
UIKitCore -[_UIAfterCACommitBlock run]
UIKitCore -[_UIAfterCACommitQueue flush]
UIKitCore _runAfterCACommitDeferredBlocks
UIKitCore _cleanUpAfterCAFlushAndRunDeferredBlocks
UIKitCore _UIApplicationFlushCATransaction
UIKitCore _UIUpdateSequenceRun
UIKitCore schedulerStepScheduledMainSection
UIKitCore runloopSourceCallback
CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
CoreFoundation __CFRunLoopDoSource0
CoreFoundation __CFRunLoopDoSources0
CoreFoundation __CFRunLoopRun
CoreFoundation CFRunLoopRunSpecific
GraphicsServices GSEventRunModal
UIKitCore -[UIApplication _run]
UIKitCore UIApplicationMain
Asset Info main AppDelegate.swift:18
0x0000000101489a24

gbreen12 avatar Oct 20 '21 21:10 gbreen12

Part of the problem is this code and database are shared among multiple apps. The "work around" is to have the user delete all our apps and reinstall and resync from the server. Then it fixes it even when using the same app version.

gbreen12 avatar Oct 20 '21 21:10 gbreen12

@gbreen12 are they sharing the database in an app group?

jsflax avatar Oct 20 '21 22:10 jsflax

This always seems to be an issue when trying to get a list of strings, Realm thinks I'm trying to access a foreign table. It's happened on multiple entities over the time I've seen it.

Yeah the database is being shared in an app group.

gbreen12 avatar Oct 20 '21 22:10 gbreen12

Any news on this issue?

I've also noticed this in production, but never managed to reproduce it myself.

Realm version: 10.25.0 (I will try to upgrade to 10.29.0 and check if this error will still appear)

Error Domain=io.realm Code=1 "No such table exists Exception backtrace: 0 Realm 0x000000010428e944 _ZNK5realm5Group7ndx2keyEm + 372 1 Realm 0x000000010428ead8 _ZNK5realm5Group15key2ndx_checkedENS_8TableKeyE + 260 2 Realm 0x00000001044c9120 _ZN5realm11ObjectStore17schema_from_groupERKNS_5GroupE + 180 3 Realm 0x0000000104518300 _ZN5realm5Realm32read_schema_from_group_if_neededEv + 132 4 Realm 0x0000000104518010 _ZN5realm5RealmC2ENS0_6ConfigENS_4util8OptionalINS_9VersionIDEEENSt3__110shared_ptrINS_5_impl16RealmCoordinatorEEENS0_13MakeSharedTagE + 424 5 Realm 0x0000000104498918 _ZN5realm5_impl16RealmCoordinator17get_unbound_realmEv + 568 6 Realm 0x0000000104497a7c _ZN5realm5_impl16RealmCoordinator12do_get_realmENS_5Realm6ConfigERNSt3__110shared_ptrIS2_EENS_4util8OptionalINS_9VersionIDEEERNS8_1

maksirol avatar Sep 15 '22 10:09 maksirol

the same: "No such table exists Exception

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=1 "No such table exists Exception backtrace: 0 Realm 0x0000000108e40ca0 _ZN5realm11NoSuchTableC1Ev + 52 1 Realm 0x0000000108e40e1c _ZNK5realm5Group15key2ndx_checkedENS_8TableKeyE + 260 2 Realm 0x0000000108f4848c _ZN5realm11Transaction17check_consistencyEv + 112 3 Realm 0x0000000108e27f68 _ZN5realm2DB4openERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEbNS_9DBOptionsE + 3312 4 Realm 0x0000000108e2a964 _ZN5realm2DB4openERNS_11ReplicationERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS_9DBOptionsE + 124 5 Realm 0x0000000108e2f04c _ZN5realm2DB6createENSt3__110unique_ptrINS_11ReplicationENS1_14default_deleteIS3_EEEERKNS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorI

mr-grey avatar Sep 20 '22 07:09 mr-grey

I don't know why you can't just create that table. At least you should tell us which table in the error messages.

KimiChiu avatar Nov 01 '22 00:11 KimiChiu

This is just my guess. Maybe it's the List field in the table causing this issues. Like the code snippet from @gbreen12 , there are two List in my table.

    @objc dynamic var id = 0

    @objc dynamic var controller: String = ""

    let mainButtons = List<Int>()

    let subButtons = List<Int>()

    @objc dynamic var createdDate: NSDate = NSDate()

    @objc dynamic var lastUpdateDate: NSDate = NSDate()

And there are bunch of fastEnumerator in the error messages, don't know if it's related.

KimiChiu avatar Dec 02 '22 11:12 KimiChiu

Me again. I changed to use comma separated String to store List<Int> and the problem solved. No more no such table errors. So I think the problem is very easy, just don't search for any table when they are String, Int or something. The workaround for developers are not to use them. Do it as the old school String type.

KimiChiu avatar Dec 13 '22 15:12 KimiChiu