I was working on a C# project to insert a record into an Amazon SQS to be consumed by another process that would take those records and process them through a different Lambda handler.
Part of the requirements was to add custom attributes to the Amazon SQS message so that the Lambda handler could make a decision based on the custom attributes value or use the custom attribute to pass along for processing decisions.
The setup seemed simple I needed something like this:
AmazonSQSClient sqsClient = new AmazonSQSClient();
Dictionary<string, MessageAttributeValue> attributes = new Dictionary<string, MessageAttributeValue>();
attributes.Add("companyId", new MessageAttributeValue() { StringValue = "1234" });
attributes.Add("type", new MessageAttributeValue() { StringValue = "comp" });
SendMessageRequest request = new SendMessageRequest();
request.QueueUrl = "someURL.fifo";
request.MessageBody = "Some body text here";
request.MessageAttributes = attributes;
request.MessageGroupId = Guid.NewGuid().ToString();
await sqsClient.SendMessageAsync(request, CancellationToken.None)
But I was greeted with the following error message:
Amazon.SQS.AmazonSQSException: Message (user) attribute 'companyId' must contain a non-empty attribute type
The answer wasn’t so obvious. I tested and knew my attribute was not null and not empty. But it turned out I was missing a key field.
When using custom attributes on Amazon SQS you MUST set the data type of the attribute.
By adding this I was able to make the error message go away.
Here is the final working code. Notice the addition of DataType=”String”
AmazonSQSClient sqsClient = new AmazonSQSClient();
Dictionary<string, MessageAttributeValue> attributes = new Dictionary<string, MessageAttributeValue>();
attributes.Add("companyId", new MessageAttributeValue() { StringValue = "1234", DataType="String" });
attributes.Add("type", new MessageAttributeValue() { StringValue = "comp", DataType = "String" });
SendMessageRequest request = new SendMessageRequest();
request.QueueUrl = "someURL.fifo";
request.MessageBody = "Some body text here";
request.MessageAttributes = attributes;
request.MessageGroupId = Guid.NewGuid().ToString();
await sqsClient.SendMessageAsync(request, CancellationToken.None)