SharePoint CSOM and “The node to be inserted is from a different document context.”

There are a few reasons you can get the “The node to be inserted is from a different document context.” error, and most of them appear to involve updating certain types of fields multiple times in the same request.  Here is an example:

using (var clientContext = new ClientContext("UrlToYourSite"))

  //Load all fields

  var fields = clientContext.Web.Fields;
  clientContext.Load(fields, f => f.Include(
    i => i.StaticName, i => i.Title));
  clientContext.ExecuteQuery();

  //Get a lookup field from your site
  var field = fields.FirstOrDefault(
    i => i.StaticName == "ALookupFieldInYourSite");

  //Update it once
  field.Update();
  clientContext.ExecuteQuery(); //Works fine

  //Update it twice
  field.Update();
  field.Update();
  clientContext.ExecuteQuery(); //Does not work fine

}

We have also seen the same error pop up when calling the SetShowInDisplayForm, SetShowInEditForm, and SetShowInNewForm in the same call, so if you have to set these values on a field, know that you have to call ClientContext.ExecuteQuery between each one to avoid the problem.

There really isn’t a great workaround for the problem aside from identifying what calls you can and can’t do in a single request and breaking them up, and unfortunately there is not a definitive list of what those calls are.  So you basically just have to start throwing in calls to ClientContext.ExecuteQuery and see where in your code you need to leave them to avoid double updates to the field in question.