javascript – 409 ‘Conflict’ Changing ContentType property of Document Library

I have about 600 items in a document library. The library has 9 content types defined in it, which is part of a reorganization to take items out of folders and make it folderless. The library is a copy of the original, and so these files have been uploaded by a move operation. All files are of the default ‘Document’ content type standard during item creation typically by uploading.

Other than ‘Edit Properties’ one-by-one for each item, and inability to use QuickEdit to change item ‘Content Type’ field (not a Column), the one way to change rapidly is REST requests. In the about 60-70 lines of code shown below, the script does the following:

  1. It has 3 serial REST requests
  2. REST request #1 gets the names and IDs of the Content Types of the doc lib, which are then stored in an array of two-property objects
  3. REST request #2 then gets all the items of the list filtered for the default “Document” content type, which are to be changed. It selects on one column, “Level 1” (referring to a top-level folder name representing a categorization that became a content type name), and its value is to be used in doing the item Content Type field update.
  4. REST request is the “POST” request supposed to do the modification. Each item request is processed in a for loop, and I put a timeout on each request of 5 seconds to space out the requests so as not to get server errors about resources.

On the “POST” request (innermost), I am getting 409 (Conflict) response errors not on one item, but the rest of the items, and I haven’t figured out what is going on. I am looking at the request object message and it shows this

{"error":{"code":"-2130575305, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"The file <filename> has been modified by i:0#.f|membership|<user identity> on 26 Feb 2021 07:46:30 -0800."}}}

I am also getting additional message from a function ‘findAjaxError()’ in my script library that seems to indicate success.

{"readyState":4,"responseText":"","status":204,"statusText":"No Content"}

But when I do a count of items with the ‘Document’ content type after a request to change only 50 items in a retrieved items list, it seems to have only been reduced by 1 item in count.

I am probably not setting up the headers correctly, or using correct method (not “POST”, but “PUT” or other?)

Has anyone tried this?

function dataTransformer() {
    RESTrequest({
        url: "https://<server+site path>/_api/web/lists/" + 
                            "getByTitle('<doc lib name>')?$expand=ContentTypes&$select=ContentTypes/Id/StringValue,ContentTypes/Name",
        method: "GET",
        successCallback: (data) => {
            let ListContentTypes = ( ), results = data.d.ContentTypes.results, DocumentContentTypeId;

            for (let result of results) {
                if (result.Name == "Document")
                    DocumentContentTypeId = result.Id.StringValue;
                ListContentTypes.push({
                    name: result.Name,
                    id: result.Id.StringValue
                });
            }
            RESTrequest({
                url: "https://<server+site path>/_api/web/lists/" + 
                            "getByTitle('<doc lib name>')/items?$select=Id,Level_x0020_1,File/Name" + 
                            "&$filter=ContentTypeId eq '" + DocumentContentTypeId + "'" +
                            "&$expand=File",
                method: "GET",
                successCallback: (data) => {
                    let ctype, idx, results = data;

                    for (idx = 0; idx < results.length; idx++) {
                        console.log("count of files to be operated on: " + results.length);
                        for (ctype of ListContentTypes)
                            if (ctype.name == results(idx).Level_x0020_1)
                                break;
                        console.log("modifying file '" + results(idx).File.Name + "'");
                        setTimeout(() => {
                            RESTrequest({
                                setDigest: true,
                                url: "https://<server+site path>/_api/web/lists/" + 
                                        "getByTitle('<doc lib name>')/items(" + results(idx).Id + ")",
                                method: "POST",
                                headers: {
                                    "X-HTTP-METHOD": "MERGE",
                                    "IF-MATCH": "*"
                                },
                                data: formatRESTBody((
                                    ("ListItemEntityTypeFullName", <list item entity type full name> ),
                                    ("ContentTypeId", ctype.id)
                                )),
                                successCallback: (data, text, reqObj) => {
                                    console.log("response data => " + 
                                        JSON.stringify(data) + 
                                        "nrequestObj => " +
                                        JSON.stringify(reqObj));
                                },
                                errorCallback: (reqObj) => {
                                    console.log(findAjaxError(reqObj));
                                }
                            });
                        }, 5000);
                    }
                },
                errorCallback: (reqObj) => {
                    console.log(findAjaxError(reqObj));
                }
            });
        },
        errorCallback: (reqObj) => {
            console.log(findAjaxError(reqObj));
        }
    });
}