CosmosDb - Errors on Inserting New Data

March 13, 2021

It’s been a while since I looked at CosmosDB (there is a chapter in my book - to the right of your screen - that covers some details of using CosmosDD, but using the MongoDB Api. To get going with Cosmos, you obviously need to create yourself a Cosmos resource in the Portal (or somehow). Once that’s done, you can interact with it using the package:



Microsoft.Azure.Cosmos

You need to create a client, database, and container:



var cosmosClient = new CosmosClient(endpointUri, primaryKey, options);

var database = await cosmosClient.CreateDatabaseIfNotExistsAsync(databaseId);            
var container = await database.CreateContainerIfNotExistsAsync(containerId, $"/{partition}");

You can then add to the container like this:



var response = await container.CreateItemAsync<ItemType>(newItem, new PartitionKey(partitionKey));

In this post, I wanted to cover a couple of errors that I got when trying to use it, and some possible solutions. For this post, I was using the Core (SQL) API.

You Need an ID

The first error was:

Microsoft.Azure.Cosmos.CosmosException: ‘Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: cdf12360b-0cbc-4575-9a1c-966f26c2351a; Reason: (Message: {“Errors”:[“The input content is invalid because the required properties - ‘id; ’ - are missing”]}

The reason here is that, when you’re writing to the DB, you need an “ID” field; or, more specifically, an “id” field. This means that either your model should have a field names “id”, or you should reference that name in a Json Property, or you can call it “Id”, and use something like this:



var options = new CosmosClientOptions()
{
    SerializerOptions = new CosmosSerializationOptions()
    {
        PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
    }
};
var cosmosClient = new CosmosClient(endpointUri, primaryKey, options);


Partition Key

The next error relates to the partition key. You typically create your container like this:



var container = await database.CreateContainerIfNotExistsAsync(containerId, $"/{partitionkey}");

And then add data to it like this:



var response = await container.CreateItemAsync<ItemType>(newItem, new PartitionKey(partitionkey));

Essentially, the rule here is this:

Whatever you specify as the partition key must exist in the payload with the exact same name.

Microsoft.Azure.Cosmos.CosmosException: ‘Response status code does not indicate success: BadRequest (400); Substatus: 1001; ActivityId: 88c1895e-a23c-5812-c205-d4503555d2cd; Reason: (Message: {“Errors”:[“PartitionKey extracted from document doesn’t match the one specified in the header”]}

You can find out what it thinks you’ve set the partition key to by using the following code:



var properties = await container.ReadContainerAsync();
Console.WriteLine(properties.PartitionKeyPath);

When I say exactly, I mean it has to be the same case in the payload; so if you’re key is Item, and you supply the field item, you’ll get this error. Such a mismatch can be caused by the camel casing that we mentioned earlier!

References

https://stackoverflow.com/questions/29725561/documentdb-replacedocument-fails



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2024