Stack Exchange
CSOM code is raising this error "Version conflict." when trying to update ListItems inside foreach
I have the following CSOM code:-
using (ClientContext context2 = Helpers.GetAppOnlyContext(properties.ItemEventProperties.WebUrl))
                {
                    try
                    {
                        //set unique permsion for the risk Value + Asset item
                        RoleDefinition readerDef = context2.Web.RoleDefinitions.GetByType(RoleType.Reader);
                        RoleDefinitionBindingCollection readOnlyBinding = new RoleDefinitionBindingCollection(context2);
                        readOnlyBinding.Add(readerDef);

                        RoleDefinition contributeDef = context2.Web.RoleDefinitions.GetByType(RoleType.Contributor);
                        RoleDefinitionBindingCollection contributeBinding = new RoleDefinitionBindingCollection(context2);
                        contributeBinding.Add(contributeDef);
                        CamlQuery camlQuery = new CamlQuery();
                        camlQuery.ViewXml = string.Format("<View Scope=\"RecursiveAll\"><Query><Where><Eq><FieldRef Name=\"RiskValueAsset\" LookupId=\"TRUE\" /><Value Type=\"Lookup\">{0}</Value></Eq></Where></Query></View>", listItemID);

                        context2.Load(context2.Web);
                        context2.ExecuteQuery();
                        ListItemCollection listItemCollection = context2.Web.GetList(context2.Web.ServerRelativeUrl + "/lists/RiskValue").GetItems(camlQuery);

                        context2.Load(listItemCollection, items => items.Include(
                                            item => item.Id,
                                            item => item["Title"],
                                            item => item.RoleAssignments
                                           ));
                        context2.ExecuteQuery();

                        ListItem listItem = context2.Web.GetList(context2.Web.ServerRelativeUrl + "/lists/Assets").GetItemById(listItemID);
                        context2.Load(listItem);
                        context2.ExecuteQuery();
                        FieldUserValue creator = listItem["Author"] as FieldUserValue;
                        foreach (ListItem listItem2 in listItemCollection)
                        {
                            
                            
                            listItem2.BreakRoleInheritance(false, false);
                            listItem2.RoleAssignments.Add(context2.Web.EnsureUser(creator.LookupValue), new RoleDefinitionBindingCollection(context2) { contributeDef });
                            listItem2.RoleAssignments.Add(context2.Site.RootWeb.SiteGroups.GetByName("Risk Users"), new RoleDefinitionBindingCollection(context2) { readerDef });
                            listItem2.RoleAssignments.Add(context2.Site.RootWeb.SiteGroups.GetByName("Risk Admins"), new RoleDefinitionBindingCollection(context2) { contributeDef });
                            listItem2.Update();
                            context2.ExecuteQuery();

                        }                           
                    }

now the foreach will run once and set the RoleAssignment, but on the second iteration it will raise this exception "Version conflict.".. any advice?
I also tried to replace the foreach with for loop as follow, but did not fix the issue:-
 for (int i = 0; i < listItemCollection.Count ; i++)
                        {


                            listItemCollection[i].BreakRoleInheritance(false, false);
                            listItemCollection[i].RoleAssignments.Add(context2.Web.EnsureUser(creator.LookupValue), new RoleDefinitionBindingCollection(context2) { contributeDef });
                            listItemCollection[i].RoleAssignments.Add(context2.Site.RootWeb.SiteGroups.GetByName("Risk Users"), new RoleDefinitionBindingCollection(context2) { readerDef });
                            listItemCollection[i].RoleAssignments.Add(context2.Site.RootWeb.SiteGroups.GetByName("Risk Admins"), new RoleDefinitionBindingCollection(context2) { contributeDef });
                            listItemCollection[i].SystemUpdate();
                            context2.ExecuteQuery();

                        }


@SharePoint TestDev,
I am able to reproduce the error using CSOM Powershell.

Please try the below code to fix it:
foreach (ListItem listItem2 in listItemCollection)
{
         
    listItem2.RefreshLoad()
    context2.ExecuteQuery()
         
    listItem2.BreakRoleInheritance(false, false);
    listItem2.RoleAssignments.Add(context2.Web.EnsureUser(creator.LookupValue), new RoleDefinitionBindingCollection(context2) { contributeDef });
    listItem2.RoleAssignments.Add(context2.Site.RootWeb.SiteGroups.GetByName("Risk Users"), new RoleDefinitionBindingCollection(context2) { readerDef });
    listItem2.RoleAssignments.Add(context2.Site.RootWeb.SiteGroups.GetByName("Risk Admins"), new RoleDefinitionBindingCollection(context2) { contributeDef });
    
    listItem2.Update();
    context2.ExecuteQuery();
} 

More Reference:

https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-server/ee539049(v=office.15)
Javascript : How to handle version conflict errors when using javascript COM?
C# SharePoint 2013 client object model list item attachment update Error: version conflict
https://sharepoint-2010-2013-2016.blogspot.com/2015/07/version-conflic-while-updating-list.html

BR

so what is causing this error?

The local object version does not match server-side object.

ok thanks for the info, but why this is happening in my case? as i am only updating the object once, so the version on both the local and server-side should be the same... is this correct?

Probably because it's in a foreach loop, meaning that you aren't updating the object only once.  Every update creates a new version.
