DynamoDb PutItem seems correct, but ValidationException: The provided key element does not match the schema

Viewed 148

I know this has been asked before and based on those answers, I am pretty sure what I have is correct. At this point, I honestly feel like I am missing something super basic.

DynamoDB connector is setup:

const AWS = require('aws-sdk');

// set up dynamoDB
const dynamoDb = new AWS.DynamoDB.DocumentClient();

I have defined a DynamoDB table with keys in serverless as such:

CampaignStreamDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5
        AttributeDefinitions:
          - AttributeName: "id"
            AttributeType: "S"
          - AttributeName: "campaign_id"
            AttributeType: "S"
        KeySchema:
          - AttributeName: "id"
            KeyType: "HASH"
          - AttributeName: "campaign_id"
            KeyType: "RANGE"
        StreamSpecification:
          StreamViewType: "NEW_AND_OLD_IMAGES"
        TableName: ${self:provider.environment.FS_CAMPAIGN_STREAM_TABLE}

I have a function that updates the table which takes BOTH the primary and range keys (third param is the status that I update a test with):

let update_test_status = async (test_id, campaign_key, test_status) => {

console.info("Updating bulk test " + test_id + " with campaign_key "+campaign_key+" to " + test_status);
    let b = true;
    const timestamp = new Date().getTime();

    const update_params = {
        TableName: process.env.FS_CAMPAIGN_STREAM_TABLE,
        Key: {
            id: test_id,
            campaign_key: campaign_key
        },
        ProjectionExpression: "#s",
        ExpressionAttributeNames: {"#s": "status"},
        UpdateExpression: "set #s=:s, updated_at=:u",
        ExpressionAttributeValues: {
            ":s": test_status,
            ":u": timestamp,
        },
        ReturnValues: "UPDATED_NEW"
    };

    try {
        let results = await dynamoDb.update(update_params).promise();

    } catch (error) {
        console.error("Could not update the record: " + error);
        test_status = "error";
        console.error("Links processed, but error updating record in DB");
        b = false;

    }
    return b;

};
    
        try {
            let results = await dynamoDb.update(update_params).promise();
    
        } catch (error) {
            console.error("Could not update the record: " + error);
            test_status = "error";
            console.error("Links processed, but error updating record in DB");
            b = false;
    
        }
        return b;
    };

and I call this function like so:

await update_test_status(item.id.S, item.campaign_key.S, "processing")

Where item is the DynamoDB record

Notes:

I have validated that both the id and key are being passed to the update method. I have tried the KEY params with and without quotes

1 Answers

in your table definition you called it campaign_id but in your code later on you called it campaign_key.

When seeing the error, you should always double (and triple) check that your name and types for the hash and range keys are the same as in the definition.

Related