Error: cannot update obj outside of write transaction, while in a write transaction

I can’t figure out the root cause of issue here. I really could use some help.

When I call .append on the questions: List property of my topic instance, it is stating that I “Cannot modify managed RLMArray outside of a write transaction.” However, you can clearly see I am in a write transaction. I’ve spent a lot of time on this and have run out of ideas what is wrong.

try! realm.write {
                            topic.questions.append(q)
                        }

Given I have other code that is working, I ended up taking a piece and fuzzing it next to the same line of code. The $questions.append call here actually succeeds and does not claim it it outside of a write transaction. The following line still errors out.’

try! realm.write {
                            let newUnit = question()
                            newUnit.owner_id = "some owner id"
                            newUnit.displayName = "this is a test question"
                            $questions.append(newUnit)
                            topic.questions.append(q)
                        }

Could there be a bug with List<> functionality?

022-09-19 23:26:59.592035-0700 sample_app_dev[34695:1405600] *** Terminating app due to uncaught exception 'RLMException', reason: 'Cannot modify managed RLMArray outside of a write transaction.'
*** First throw call stack:
(
	0   CoreFoundation                      0x0000000111950604 __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x000000010f4aaa45 objc_exception_throw + 48
	2   sample_app_dev                      0x000000010b198de6 _ZL10throwErrorP15RLMManagedArrayP8NSString + 134
	3   sample_app_dev                      0x000000010b199e20 _ZL15translateErrorsIZL11changeArrayIZL11changeArrayP15RLMManagedArray16NSKeyValueChangemU13block_pointerFvvEE4$_22EvS2_S3_S5_OT_EUlvE_EDaS8_ + 64
	4   sample_app_dev                      0x000000010b199be8 _ZL11changeArrayIZL11changeArrayP15RLMManagedArray16NSKeyValueChangemU13block_pointerFvvEE4$_22EvS1_S2_S4_OT_ + 88
	5   sample_app_dev                      0x000000010b1943ad _ZL11changeArrayP15RLMManagedArray16NSKeyValueChangemU13block_pointerFvvE + 77
	6   sample_app_dev                      0x000000010b193a67 _ZL15RLMInsertObjectP15RLMManagedArrayP11objc_objectm + 327
	7   sample_app_dev                      0x000000010b1938e0 -[RLMManagedArray addObject:] + 64
	8   sample_app_dev                      0x000000010b48444c $s10RealmSwift4ListC6appendyyxF + 220
	9   sample_app_dev                      0x000000010b012834 $s14sample_app_dev21relate_topic_questionV4bodyQrvg7SwiftUI4ViewPAEE9listStyleyQrqd__AE04ListL0Rd__lFQOyAE0M0Vys5NeverOAE7ForEachVy05RealmH07ResultsVyAA0F0CGs6UInt64VAgEE4task8priority_QrScP_yyYaYbctFQOyAgEE11environmentyQrs15WritableKeyPathCyAE17EnvironmentValuesVqd__G_qd__tlFQOyAA0d5_row_e1_F0V_AP0Q0VQo__Qo_GG_AE05InsetmL0VQo_yXEfU0_A10_yXEfU_A9_ATcfU_yyYaYbcfU_yyXEfU_ + 468
	10  sample_app_dev                      0x000000010afcd5df $ss5Error_pIgzo_ytsAA_pIegrzo_TR + 15
	11  sample_app_dev                      0x000000010b0189b4 $ss5Error_pIgzo_ytsAA_pIegrzo_TRTA + 20
	12  sample_app_dev                      0x000000010b4e37c3 $s10RealmSwift0A0V5write16withoutNotifying_xSaySo20RLMNotificationTokenCG_xyKXEtKlF + 275
	13  sample_app_dev                      0x000000010b0124d2 $s14sample_app_dev21relate_topic_questionV4bodyQrvg7SwiftUI4ViewPAEE9listStyleyQrqd__AE04ListL0Rd__lFQOyAE0M0Vys5NeverOAE7ForEachVy05RealmH07ResultsVyAA0F0CGs6UInt64VAgEE4task8priority_QrScP_yyYaYbctFQOyAgEE11environmentyQrs15WritableKeyPathCyAE17EnvironmentValuesVqd__G_qd__tlFQOyAA0d5_row_e1_F0V_AP0Q0VQo__Qo_GG_AE05InsetmL0VQo_yXEfU0_A10_yXEfU_A9_ATcfU_yyYaYbcfU_TY0_ + 354
	14  sample_app_dev                      0x000000010b0183c1 $s14sample_app_dev21relate_topic_questionV4bodyQrvg7SwiftUI4ViewPAEE9listStyleyQrqd__AE04ListL0Rd__lFQOyAE0M0Vys5NeverOAE7ForEachVy05RealmH07ResultsVyAA0F0CGs6UInt64VAgEE4task8priority_QrScP_yyYaYbctFQOyAgEE11environmentyQrs15WritableKeyPathCyAE17EnvironmentValuesVqd__G_qd__tlFQOyAA0d5_row_e1_F0V_AP0Q0VQo__Qo_GG_AE05InsetmL0VQo_yXEfU0_A10_yXEfU_A9_ATcfU_yyYaYbcfU_TATQ0_ + 1
	15  SwiftUI                             0x0000000112a435e3 $s7SwiftUI13_TaskModifierV05InnerD033_293A0AF83C78DECE53AFAAF3EDCBA9D4LLV4body7contentQrAA05_ViewD8_ContentVyAFG_tFyycfU_yyYaYbcfU_TQ0_ + 1
	16  SwiftUI                             0x0000000112a49a1a $s7SwiftUI13_TaskModifierV05InnerD033_293A0AF83C78DECE53AFAAF3EDCBA9D4LLV4body7contentQrAA05_ViewD8_ContentVyAFG_tFyycfU_yyYaYbcfU_TATQ0_ + 1
	17  SwiftUI                             0x0000000112a45cd5 $sxIeghHr_xs5Error_pIegHrzo_s8SendableRzs5NeverORs_r0_lTRyt_Tg5TQ0_ + 1
	18  SwiftUI                             0x0000000112a48ec1 $sxIeghHr_xs5Error_pIegHrzo_s8SendableRzs5NeverORs_r0_lTRyt_Tg5TATQ0_ + 1
	19  libswift_Concurrency.dylib          0x000000010f8dc941 _ZL23completeTaskWithClosurePN5swift12AsyncContextEPNS_10SwiftErrorE + 1
)

Well, forums for the win.

A “similar topic” on this thread was displayed for:

From Jason on that thread:
" item.isFavorite.toggle() will not work because you need to call the projected value (using the dollar sign). Using the $ will effectively open a write transaction, enabling the set behaviour previously mentioned."

In my code, I added a $ and now it works.

try! realm.write {
$topic.questions.append(q)
}

@Jason_Flax in the context of my issue, why would adding a $ fix it, given I had already been using the realm.write syntax to open a write transaction?

Hm, still an issue with a different permutation.

I gave simplified code. In my full use case, I am passing topic.questions as a RealmSwift.List parameter to a child view named “topic_questions”. This child view is calling topic_questions.append(q). This still throws the same error. Trying to add a $ on the child view doesn’t compile. If I pass the entire topic object to the child view, and then call $topic.questions.append in the child view, that works.

Any way to be able to pass a realm List to a child view and modify it?

So this topic is marked as solved. Is it or is there more to it?

I marked it solved given a workaround is listed in the comment.

I do have two remaining questions though:

  1. @Jason_Flax in the context of my issue, why would adding a $ fix it, given I had already been using the realm.write syntax to open a write transaction?

  2. How can I update a RealmSwift.List from a child view as a parameter? I get the same error that it needs to be within a write transaction, although it is. The $ workaround from #1 does not work for this case.

I think some further context is needed.

When coding in SwiftUI, the property wrappers like @ObservedResults make it so writes can can be done without explicitly opening a write transaction. In the initial question, .write is being called. So are you not using SwiftUI? Are you/are you not using @ObservedResults and other wrappers?

Can you provide a short and complete coding example so we understand your use case? I am not sure $ is the answer here.