In this post I’m going to show you how to bypass a limitation of SharePoint Designer 2013 workflows that prevents us from directly updating a managed metadata field.
The proposed solution works for both SharePoint 2013 On Premises and Online (Office 365) and uses only the SharePoint Designer 2013 built-in actions.
Scenario
We have a custom list item with a managed metadata (taxonomy) field in it. We need to update the taxonomy field using a SharePoint Designer 2013 workflow.
Problem
When you try to update a managed metadata field through the “Update List Item” action a BadRequest error occurs with the following message:
An unexpected ‘PrimitiveValue’ node was found when reading from the JSON reader. A ‘StartObject’ node was expected.
This happens because SharePoint is expecting a complex type. However, any value you supply through a built-in list action in SharePoint Designer gets wrapped in quote marks and treated as a string literal…
So, how to get around this limitation?
Solution
When you add a taxonomy field in SharePoint, you are really adding two fields:
- The first one is the visible field you see and edit
- The second one is a hidden note field which holds the values for its associated field as plain text
Let’s say you add a taxonomy field called “TaxonomyField”, SharePoint will automatically add a note field called “TaxonomyField_0”.
Here is the solution to all our problems:
If we update the hidden field “TaxonomyField _0” with a well formatted text value then its associated taxonomy field gets updated as well.
Great!
We can update a hidden field in a SharePoint Designer 2013 workflow only using REST with the “Call HTTP Web Service” action.
So, all we need to do now is to get the internal name of our hidden field and set its value with a REST call using the format
Term1Name|Term1Guid
For a multi value managed metadata field we need to separate the entries with a semicolon, like this:
Term1Name|Term1Guid;Term2Name|Term2Guid
Let’s see how to do this in more detail…
Steps
1. Get the hidden field internal name
Finding the internal (static) name of the hidden field can be done by using the SharePoint REST API via a browser using a URL like this
https://site/_api/web/lists/getbytitle('listtitle')/fields
In the example below the static name for our hidden field is “l4ea604b343942df935ba60a0e9dd7ad”.
2. Get the term name and guid
In the Term Store Management Tool for your site (Site Settings > Site Administration > Term Store Management) find the term you want to use to update the taxonomy field and get its name and guid.
In the example below the name and guid of our term are respectively “Term1” and “6dfad373-fc10-4a84-b83f-efa262c18275”.
3. Get the list item type
To get the list item type we need to use the SharePoint REST API via a browser again using a URL like this
https://site/_api/web/lists/getbytitle('listtitle')
Then we must get the value for the “d:ListItemEntityTypeFullName” element.
In the example below the list item type is “SP.Data.TaxonomyListListItem”.
4. Create the headers dictionary
Now we have all the information we need to start working with our SharePoint Designer 2013 workflow.
First of all we must build a dictionary to store some headers, specifically the following ones:
Accept: application/json;odata=verbose Content-Type: application/json;odata=verbose Content-Length: <length of post body> X-HTTP-Method: MERGE If-Match: *
5. Create the metadata dictionary
Next we need to create a dictionary to store our metadata.
This dictionary will only contain one entry for the list item type we’ve obtained previously:
type: SP.Data.TaxonomyListListItem
6. Create the data dictionary
Next, we need one more dictionary that will contain our request data.
The dictionary must have an entry with key “__metadata” (note the double underscore before the “metadata” string) with its value set to the previously created metadata dictionary.
We also need to add another entry in the data dictionary with its key set to the internal name of our hidden field and its value having the format “TermName|TermGuid”.
__metadata: <metadata dictionary> l4ea604b343942df935ba60a0e9dd7ad: Term1|6dfad373-fc10-4a84-b83f-efa262c18275
7. Call the SharePoint REST service
Finally, we are ready to call the SharePoint REST service to update our taxonomy field. To do this we need to insert the “Call HTTP Web Service” action in our workflow.
The action URL must be constructed dynamically to point to the current item like this
https://site/_api/web/lists/getbytitle('listtitle')/items(n)
The action verb must be set to POST.
Then we need to set the request headers to the headers dictionary and the request content to the data dictionary.
Conclusion
This is how the complete workflow should look like:
Now we can publish and run it. Once it is over we’ll have our taxonomy field correctly updated.
Hello Maria, I tried to follow your great blog about this, but when I do the Post I just get the result “bad request” do you have any idea what it might be?
LikeLike
Hi Knut!
That error usually happens when there is something wrong with your request headers, body or endpoint.
Typing errors can easily occur…
If you send me an email at blog@mariagraziamerlo.com with some screenshots of the workflow details I can try to help you.
Bye,
Maria Grazia.
LikeLike
Hello,
I get the result “bad request”, too. I just copied and paste the parameter from this article setting the values of my site.
Can anyone help me?
Thanks
Philipp
LikeLike
How would you remove a value already in the field? This works great for adding.
LikeLike
Hi Nicholas!
Simply putting an empty string as value for the field in the data dictionary for the rest request (step 6 of my post) works for me. I’ve tried both with a single and multi value metadata field in a SharePoint Online environment.
LikeLike
HA! I tried everything else but that! (face palm!) Thanks!
LikeLike
Hi,
thanks for this great post. I followed your instructions step by step but alway get an internal Server Error. Below is the error message. It’s in german but it says something like “Minimum one filed is not installed correctly. Go to list settings to delete the fields…”
I tried on different lists with the same result. Any Idea what the error could be?
{“error”:{“code”:”-2130575340, Microsoft.SharePoint.SPException”,”message”:{“lang”:”de-DE”,”value”:”Mindestens ein Feld ist nicht richtig installiert. Wechseln Sie zur Listeneinstellungsseite, um diese Felder zu löschen.”}}}
LikeLike
Hi Martin.
Try to double check the field names you are using in your rest requests for typos.
LikeLike
Hi Maria,
thanks for you answer. What I found out is, that ist works fine if I create a Meta-Data column in the SharePoint list directly. But when I try the same with a website-column then I get the error message described above.
Is there any difference in doing this with a website-column?
LikeLike
Hi Martin.
I’ve tested the steps described in my post with a site column in an Office 365 environment (SharePoint Online) and it works. Give me some time to verify your point also in a SharePint 2013 On-Premises environment and I will give you a feedback.
Thank you very much for your contribution.
LikeLike
Hi,
Any update on this problem?
I am also getting this error. “One or more field types are not installed properly. Go to the list settings page to delete these fields.”
I have double checked the field names aswell. In my case, this worked fine on Document Libraries but i am getting this error when I update Managed metadata columns in a list. I also want to point out that my term set has two levels in list.
LikeLike
Hi Maria,
Thank you for the detailed steps.
In SharePoint online, It is working fine if the column name does not contain any special characters (spaces and questions). If it contains, the REST API is returning 500 response.
Below is the exact error message I received when tried to insert some data into a column (Managed Metadata) whose name contains spaces and question mark symbol.
“One or more field types are not installed properly. Go to the list settings page to delete these fields.”
LikeLike
If your workflow is copying a managed metadata field value from a source item (e.g. the associated custom task item) to a destination item (e.g. CurrentItem), you can read the value of MyMetadataField_0 from the source item and use it for the Step 6 data value. The MyMetadataField_0 field is readable, just not writable unless you use the REST call. Also, you can omit the Content-Length header altogether.
LikeLike
I just wanted to comment on the problem: I am also getting this error. “One or more field types are not installed properly. Go to the list settings page to delete these fields.”
I opened a case with MS and they figured out that if the column has other than alphanumeric characters, this problem occurs. If you define your column (no matter if it’s site or list column), it works just fine.
I hope this will help someone.
LikeLike
I meant to say – other than alphanumeric characters in a Column name.
LikeLike
Thank you, Thank you – was beating my head against a wall for 5 hours until I saw this gem.
LikeLike
Hello, is this also working for a document library? I can’t do it…I always get “BadRequest”
LikeLike
Hello and Thanks for sharing this How-To!
Indeed the last two hours I was facing “Bad Request”, too.
Maybe someone makes the same mistake in the future:
When you assign the Metadata Dictionary to the Data Dictionary, with the __metadata attribute, make sure to select the correct datatype! By default this is string and must be changed to dictionary! (As the screenshot above shows)
the devil is in the detail
SP2016 Landscape
LikeLike
Back again! Thanks for the help before.
Is this process the same with SharePoint Online and Flow?
LikeLike
Yes Nick, it is the same for SharePoint Online and Flow where you can use SharePoint API directly.
LikeLike
Great article! It’s helped in several scenarios.
I’ve recently run into a snag when trying to use Key Filters. The filter functionality does not recognize the values set using a workflow. The column itself shows the correct value, but if I edit properties for the item it will show the managed metadata value with a red, dashed underline meaning it has not “resolved” to a term. I’m assuming this is also why Key Filters is not working.
I confirmed the workflow is using the correct term GUID. And it IS setting the column value but something is not making the connection to actually resolve it to a value. Is another step needed to somehow “resolve” the field after the term|termGUID is set?
LikeLike
Dear Amy, thank you for your question. In fact, the procedure described in the blog post is complete and no other step is required for the given scenario.
Maria Grazia.
LikeLike