Issues with creating new Cosmos DB documents with Logic App

Recently I had to build a solution for a customer. One part was to create order documents in a Cosmos DB using a Logic App. Sounds easy, however, I struggled a bit because of a simple thing and thought that this could help others. So here we go.

The Logic App will be HTTP-triggered. The request body will contain the order details. For this blog post I simplified the procedure (less order details, no schema validation etc.). After the trigger I use a “Create or update document” step, connect to the Cosmos DB and use the body to create the document

image

Once prepared, I use a simple PowerShell script to test the Logic App. Here you can also see how the body is constructed.

$uri = https://prod-35.westeurope.logic.azure.com:443/workflows/58a………”
$id = [guid]::NewGuid()
$product = “Office 2003 Professional”
$orderdate = get-date -format s
$person = “Marcel Zehner”
$country = “Switzerland”
$Status = “Ordered”

$body = @{
“id” = $id;
“product” = $product;
“orderdate” = $orderdate;
“person” = $person;
“country” = $country;
“status” = $status
} | ConvertTo-Json

Invoke-WebRequest -Uri $uri -Body $body -Method POST -ContentType application/json

The Logic App triggers, but later fails. The request body looks OK, but the document has not been created. Let’s have a look at the error message.

image

image

{

“code”: “BadRequest”,

“message”: “Message: {\”Errors\”:[\”The partition key supplied in x-ms-partitionkey header has fewer components than defined in the the collection.\”]}\r\nActivityId: 397f8bfc-b4d6-461d-934b-ef834182eb3a, Request URI: /apps/36834417-c2b8-4524-871e-e3247817af32/services/cad59f1d-0db5-448a-b8ce-ab8e45f2f3d9/partitions/2e968e2a-42b1-40fe-9b91-1c294c301efc/replicas/131934563705646138p/, RequestStats: \r\nRequestStartTime: 2019-02-05T17:25:00.7030395Z, Number of regions attempted: 1\r\n, SDK: Microsoft.Azure.Documents.Common/2.1.0.0″

}

So there seems to be an issue with the Cosmos DB partition key. This key is used for scaling, so let’s have a look at the collection configuration. The “orders” collection uses a partition key “country”.

image

Now back in the Logic App designer you will discover that you can add a partition key value to the step. Let’s do that. For now I just hardcode the value to see if this works. But nope, after firing the PowerShell script the Logic App fails again. But this time with a different error message.

image

image

{

“code”: “BadRequest”,

“message”: “Partition key [Switzerland] is invalid.\r\nActivityId: 31c27f0b-e75a-4fa7-9aac-9a4d777e0529, \r\nRequestStartTime: 2019-02-05T16:07:12.1086065Z, Number of regions attempted: 1\r\n, Microsoft.Azure.Documents.Common/2.1.0.0″

}

One interesting thing is, that the value is shown in brackets which means that it is interpreted as an array. Back at the drawing board I changed the hardcoded value to something different and added quotation marks. Again, another error message. This time it’s a bit clearer. The partition key value obviously MUST be in quotation marks and it MUST match the value for the same key in the payload.

{

“code”: “BadRequest”,

“message”: “Message: {\”Errors\”:[\”PartitionKey extracted from document doesn’t match the one specified in the header\”]}\r\nActivityId: 3c500c0c-c2ed-4587-b16f-4565877d87b6, Request URI: /apps/36834417-c2b8-4524-871e-e3247817af32/services/cad59f1d-0db5-448a-b8ce-ab8e45f2f3d9/partitions/2e968e2a-42b1-40fe-9b91-1c294c301efc/replicas/131934563705646138p/, RequestStats: \r\nRequestStartTime: 2019-02-05T16:10:24.7924046Z, Number of regions attempted: 1\r\n, SDK: Microsoft.Azure.Documents.Common/2.1.0.0″

}

After changing everything properly, it worked like a charm.

– Partition key in quotation mark
– “Country” value identical to the one submitted in the request body

image

image

The last step was bringing the value for the partition key dynamically to the field. I use a “Parse JSON” step for that. In this step, the request body is parsed, so that afterwards all individual key-value pairs can easily be accessed.

image

{
“type”: “object”,
“properties”: {
“id”: {
“type”: “string”
},
“person”: {
“type”: “string”
},
“status”: {
“type”: “string”
},
“product”: {
“type”: “string”
},
“orderdate”: {
“type”: “string”
},
“country”: {
“type”: “string”
}
}
}

Finally, I use the dynamic “country” value from the Parse JSON output in the partition key property. And don’t miss the quotation marks!

image

Firing the script again now does exactly what I need.

image

I found this a bit confusing and also discovered that this is/was an issue for many folks out there – not only for the ones using Logic App but trying to create new Cosmos DB documents in general. I hope this blog post can help out a bit …

Cheers
Marcel

About Marcel Zehner

Microsoft Azure MVP
This entry was posted in Azure and tagged , , , , , , , . Bookmark the permalink.

18 Responses to Issues with creating new Cosmos DB documents with Logic App

  1. New Logicer says:

    I did the same. But I still get error “PartitionKey extracted from document doesn’t match the one specified in the header”. The Partition Key Value in the Input section has correct value in quote, match the document. Some people suggest it has to be an array?

    • Are you sure you have the exact same property in the body? Then it should definitely work.

    • Riyaz says:

      yeah me too facing the same issue even after exactly following the steps.

      • Riyaz says:

        the issue was the mismatch in partition key..turns out the partition key i gave while creating the db was never present in the json payload. It was a typo with camel case and pascal case each. Now it is working as a charm after I corrected it.

      • Thanks for the update. As mentioned, the partition key is needed in the JSON payload. Without it will not work.

        Cheers, Marcel

  2. In the code view make sure the header section of the CosmosDB Action looks like what I have below:
    “headers”: {
    “x-ms-documentdb-partitionkey”: “@{body(‘Parse_JSON’).country}”
    },

    Notice: when trying to use the “Add New Parameter” it formats it as x-ms-documentdb-RAW-partitionkey, which causes errors, and as Marcel mentioned you need it in your body which your screenshot shows.

    I think it’s the logic app connector bug mentioned above, where it add’s “RAW” to the parameter declaration.

    The PartitionKey should always point to the value of the field you are partitioning on, so it should be the value of “country” that is passed in the root of the document body, and it of course needs to match what the CosmosDB Collection expects as the partition key (as far as it’s naming in the document body) I.E. if the CosmosDB Collection used “nation” instead of “country” than your document body would need to declare it as “nation” instead of “country” to set it.

  3. ewehrmann says:

    Thanks for the article, it saved me some time!

  4. Richard says:

    Thank you all for the above post and replies. I was trying to load-in a couple of JSON items via PowerShell into a CosmosDB collection and was specifying the partition key definition rather than the actual value of the key for the item. Reading through the above it was an easy fix;

    # Insert docs into Collection
    $json = Get-Content “C:\Users\*****\OneDrive – Onomi\GitHub\DP-200-Implementing-an-Azure-Data-Solution\Labfiles\Starter\DP-200.4\ClothingItems.json” | Out-String | ConvertFrom-Json
    $cosmosDbContext = New-CosmosDbContext -Account $accountName -Database $databaseName -ResourceGroup $resourceGroupName
    foreach($i in $json){
    $document = $i | ConvertTo-Json | Out-String
    New-CosmosDbDocument -Context $cosmosDbContext -CollectionId $containerName -DocumentBody $document -PartitionKey $i.productId
    }

  5. Eric Charbonnier says:

    Thanks for this article that really help me.

  6. Karan says:

    Hello, we have non-partition collection for our cosmos DB, And I am using Android SDK to create a document using databaseId and collectionId. Also, i have taken the partition key as property and set as null. still getting the error “partition key supplied in x-ms-partitionkey header has fewer components than defined in the collection”

    can anyone help me to come out from this ?

  7. kudos man, thanks for this tip. saved me loads of time needless troubleshooting! Documentation could be better for soure.

  8. ranjanpandey2009 says:

    Thank you. It helped me fix the issue.

  9. This one really did save some time for me today! Hope they will also introduce Native Mongo API support for the Logic Apps

  10. Tom says:

    Thank you for this post Marcel. Saved me a lot of time! I encountered the same problem and I am equally confused by the solution… Why??

  11. Moisés Moraes says:

    Thank you.
    By the way, for create or update, the parameter IsUpsert most be set to true.

Leave a Reply to Richard Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s