Crash - Duplicate keys of type 'AnyHashable' were found in a Dictionary.
Environment
- Xcode version: Version 16.2 (16C5032a)
- iOS version: iOS 18.2.1 (22C161)
- Devices affected: all
- Maps SDK Version: 11.9.0 (and possibly 11.8.0)
Observed behavior and steps to reproduce
Crash with: ' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion. > Fatal error
Happens randomly during View update, various devices, could not yet be observed in debug Affects stability of the app
Expected behavior
No crash
Notes / preliminary analysis
in final class AnnotationManagerImpl<AnnotationType: Annotation & AnnotationInternal & Equatable>: AnnotationManagerImplProtocol {
func set(newAnnotations: [(AnyHashable, AnnotationType)]) {
var resolvedAnnotations = [AnnotationType]()
newAnnotations.forEach { elementId, annotation in
var annotation = annotation
let stringId = idsMap[elementId] ?? annotation.id
idsMap[elementId] = stringId
Duplicate keys of type 'AnyHashable' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion. po idsMap shows: Simultaneous accesses to 0x158d4cfd0, but modification requires exclusive access. Previous access (a modification) started at closure #1 in AnnotationManagerImpl.set(newAnnotations:) + 3120 (0x10b108460).
annotation.id = stringId
annotation.isDraggable = false
annotation.isSelected = false
resolvedAnnotations.append(annotation)
}
// TODO: evict old ids
annotations = resolvedAnnotations
}
Sentry Thread Stack Trace
ibswiftCore +0x01172c
_assertionFailure(_: StaticString, _: String, flags: UInt32
libswiftCore +0x198624
KEY_TYPE_OF_DICTIONARY_VIOLATES_HASHABLE_REQUIREMENTS(Any.Type)
+0x60ac70
specialized _NativeDictionary.mutatingFind(_: A, isUnique: Bool) (<compiler-generated>)
+0x2dd60c
specialized _NativeDictionary.setValue(_: __owned B, forKey: A, isUnique: Bool) (<compiler-generated>)
+0x2dd60c
specialized Dictionary._Variant.setValue(_: __owned B, forKey: A) (<compiler-generated>)
+0x2c78f4
specialized Dictionary.subscript.setter (<compiler-generated>)
+0x2c78f4
**closure #1 (AnyHashable, A) in AnnotationManagerImpl.set(newAnnotations: [(AnyHashable, A)]) (AnnotationManagerImpl.swift:211)**
+0x2caa74
thunk for @callee_guaranteed (@in_guaranteed AnyHashable, @in_guaranteed A) -> () (<compiler-generated>)
libswiftCore +0x0f4c9c
Sequence.forEach((A.Element))
+0x2c779c
**AnnotationManagerImpl.set(newAnnotations: [(AnyHashable, A)]) (AnnotationManagerImpl.swift:208)**
+0x346c68
MountedAnnotationGroup.update(manager: A, context: MapContentNodeContext) (MountedAnnotationGroup.swift:61)
+0x347048
MountedAnnotationGroup.tryUpdate(from: MapContentMountedComponent, with: MapContentNodeContext) (MountedAnnotationGroup.swift:52)
+0x3471bc
protocol witness for MapContentMountedComponent.tryUpdate(from: MapContentMountedComponent, with: MapContentNodeContext) in conformance MountedAnnotationGroup<A> (<compiler-generated>)
+0x359928
MapContentNode.update<A>(with: A) (MapContentNode.swift:97)
+0x330c50
MapContent.update(MapContentNode) (MapContent.swift:93)
+0x330ac0
$s10MapboxMaps15TupleMapContentVyACyqd__qd__Qp_tGqd__qd__QpcRvd__qd__qd__Qp_tRszAA0dE0Rd__lufcyAA0dE4NodeCcfU_yAGyXEXEfU_ (MapContent.swift:24)
+0x3308d8
MapContentNode.withChildrenNodes((())) (MapContentNode.swift:42)
+0x3308d8
$s10MapboxMaps15TupleMapContentVyACyqd__qd__Qp_tGqd__qd__QpcRvd__qd__qd__Qp_tRszAA0dE0Rd__lufcyAA0dE4NodeCcfU_ (MapContent.swift:23)
+0x1f067c
specialized thunk for @escaping @callee_guaranteed (@in_guaranteed A) -> () (<compiler-generated>)
+0x359850
MapContentNode.update<A>(with: A) (MapContentNode.swift:82)
+0x330c50
MapContent.update(MapContentNode) (MapContent.swift:93)
+0x3312d8
closure #1 (()) in OptionalMapContent.visit(MapContentNode) (MapContent.swift:79)
+0x331190
MapContentNode.withChildrenNodes((())) (MapContentNode.swift:42)
+0x331190
OptionalMapContent.visit(MapContentNode) (MapContent.swift:77)
+0x359850
MapContentNode.update<A>(with: A) (MapContentNode.swift:82)
+0x330c50
MapContent.update(MapContentNode) (MapContent.swift:93)
+0x330ac0
$s10MapboxMaps15TupleMapContentVyACyqd__qd__Qp_tGqd__qd__QpcRvd__qd__qd__Qp_tRszAA0dE0Rd__lufcyAA0dE4NodeCcfU_yAGyXEXEfU_ (MapContent.swift:24)
+0x3308d8
MapContentNode.withChildrenNodes((())) (MapContentNode.swift:42)
+0x3308d8
$s10MapboxMaps15TupleMapContentVyACyqd__qd__Qp_tGqd__qd__QpcRvd__qd__qd__Qp_tRszAA0dE0Rd__lufcyAA0dE4NodeCcfU_ (MapContent.swift:23)
+0x1f067c
specialized thunk for @escaping @callee_guaranteed (@in_guaranteed A) -> () (<compiler-generated>)
+0x359850
MapContentNode.update<A>(with: A) (MapContentNode.swift:82)
+0x330c50
MapContent.update(MapContentNode) (MapContent.swift:93)
+0x35d26c
MapContentNodeContext.update(mapContent: MapContent, root: MapContentNode) (MapContentReconciler.swift:75)
+0x35ca48
MapContentReconciler.update(with: MapContent) (MapContentReconciler.swift:47)
+0x64aa68
MapContentReconciler.content.didset (MapContentReconciler.swift:8)
+0x64aa68
MapContentReconciler.content.setter (MapContentReconciler.swift)
+0x64aa68
StyleManager.setMapContent(()) (StyleManager.swift:461)
+0x68de68
MapBasicCoordinator.update(viewport: ConstantOrBinding<Viewport>, deps: MapDependencies, layoutDirection: LayoutDirection, animationData: ViewportAnimationData?) (MapBasicCoordinator.swift:91)
+0x689044
Map.updateUIViewController(_: UIViewController, context: UIViewControllerRepresentableContext<Map>) (Map.swift:143)
Additional links and references
Thank you @thomas-hensel for reporting this, I have created an internal issue to track the progress of this https://mapbox.atlassian.net/browse/MAPSIOS-1713
@thomas-hensel Hi, do you have any scenario to reproduce it?
As I needed a quick solution I rewrote my code segment, that gave these crashes.
From what I remember, it was like this:
CircleAnnotationGroup(locations, id: \.self) { location in
CircleAnnotation(centerCoordinate: CLLocationCoordinate2DMake(location.latitude, location.longitude) , isDraggable: true)
}
locations is a SwiftData object collection. It has crashed very randomly once a day and I could not see a pattern, unfortunately.
I rewrote it to
ForEvery(locations) { location in
CircleAnnotation(centerCoordinate: CLLocationCoordinate2DMake(location.latitude, location.longitude) , isDraggable: false)
}
and the error did not pop up since then.