skip to Main Content

I have been stuck for quite a while trying to fix the ValidationException error. I am using Javascript v3 and DynamoDBClient.

Things I have done:

  • Made sure the aws credentials can be used with my standalone react application (still in the process of self-learning AWS)
  • Did a simple ScanCommand to bring over data from DynamoDB to frontend (works)
  • Verified that data is passed to the backend from frontend sucessfully (works)

This is my DynamoDB table design:

The table name is Users,
enter image description here

My credential and access key: (root user not created user)

enter image description here

For backend, I am using Express js:

import Express from "express";
import cors from "cors";
import dotenv from "dotenv";
import path from "path";
import bodyparser from "body-parser";
import {DynamoDBClient} from "@aws-sdk/client-dynamodb";
import {GetCommand} from "@aws-sdk/lib-dynamodb";
import {fromEnv} from "@aws-sdk/credential-providers"; // This is required
import bcrypt from 'bcrypt';

const aws_creds = path.join(process.cwd(), "../", "env/", "awsbackend.env")
console.log("ENV File: " + aws_creds.toString());

// Load environment variable into process environment
dotenv.config({path: aws_creds});

// NOTE: This will only work after loading to process environment
console.log(process.env.backendport);
console.log(process.env.AWS_ACCESS_KEY_ID);

var capstone_proj = Express();

capstone_proj.use(cors());

capstone_proj.use(bodyparser.json());

var creds = fromEnv(); // No matter what, this is required

let DBnoSQL = new DynamoDBClient({
  region: process.env.region,
  credentials: creds,
});

capstone_proj.post('/login', async (req, res) => {
  const { Usrname, Password } = req.body;

  console.log(req.body);

  try {
    const command = new GetCommand({
      TableName: "Users",
      Key : {
         "Username": {S: Usrname}
      }
    });
    const data = await DBnoSQL.send(command);

    if (!data.Item) {
      return res.status(404).json({ error: 'Wrong login credentials' });
    }

    const isPasswordValid = await bcrypt.compare(
      Password,
      data.Item.Password_Hash.S,
    );

    if (isPasswordValid) {
      return res.status(200).json({ message: "Login successful" });
    } else {
      return res.status(401).json({ message: "Wrong login credentials" });
    }
  } catch (error) {
    console.error("Error:", error);
    return res.status(500).json({ message: "Internal server error" });
  }
});


capstone_proj.listen(process.env.backendport, () => {
    console.log("Backend listening on " + process.env.backendport)
})

//getdata(); 

The error that I am getting:

Error: ValidationException: The provided key element does not match the schema
    at throwDefaultError (D:Coding WorkspacesCapstonebackend-AWSnode_modules@smithysmithy-clientdist-cjsdefault-error-handler.js:8:22)
    at D:Coding WorkspacesCapstonebackend-AWSnode_modules@smithysmithy-clientdist-cjsdefault-error-handler.js:18:39
    at de_GetItemCommandError (D:Coding WorkspacesCapstonebackend-AWSnode_modules@aws-sdkclient-dynamodbdist-cjsprotocolsAws_json1_0.js:1554:20)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async D:Coding WorkspacesCapstonebackend-AWSnode_modules@smithymiddleware-serdedist-cjsdeserializerMiddleware.js:7:24
    at async D:Coding WorkspacesCapstonebackend-AWSnode_modules@aws-sdklib-dynamodbdist-cjsbaseCommandDynamoDBDocumentClientCommand.js:26:34
    at async D:Coding WorkspacesCapstonebackend-AWSnode_modules@aws-sdkmiddleware-signingdist-cjsawsAuthMiddleware.js:14:20
    at async D:Coding WorkspacesCapstonebackend-AWSnode_modules@smithymiddleware-retrydist-cjsretryMiddleware.js:27:46
    at async D:Coding WorkspacesCapstonebackend-AWSnode_modules@aws-sdkmiddleware-loggerdist-cjsloggerMiddleware.js:7:26
    at async file:///D:/Coding%20Workspaces/Capstone/backend-AWS/index.js:46:18 {
  '$fault': 'client',
  '$metadata': {
    httpStatusCode: 400,
    requestId: 'N9OAQBOPOSM5NV38FE5FNCLMQ3VV4KQNSO5AEMVJF66Q9ASUAAJG',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  __type: 'com.amazon.coral.validate#ValidationException'
} 

2

Answers


  1. Considering the error, There could be two possible problems here:

    1. You are only providing half of your primary key. For the primary
      key, you must provide all of the attributes. For example, with a
      simple primary key, you only need to provide a value for the
      partition key. For a composite primary key, you must provide values
      for both the partition key and the sort key.
    2. Field’s value should have a proper data type as per the table. It is
      always better to double-check the data type of the value being
      passed. Maybe, you have defined the primary key as a Number and you
      are passing a string value in the getItem call.
    Login or Signup to reply.
  2. The thing to not here is this:

    at async D:Coding WorkspacesCapstonebackend-AWSnode_modules@aws-sdklib-dynamodbdist-cjsbaseCommandDynamoDBDocumentClientCommand.js:26:34

    Your app is trying to use DynamoDBDocumentClientCommand but you are not using the document client, you use the low-level client.

    import {DynamoDBClient, GetItemCommand} from "@aws-sdk/client-dynamodb";
    //import {GetCommand} from "@aws-sdk/lib-dynamodb";
    
      const command = new GetItemCommand({
          TableName: "Users",
          Key : {
             "Username": {S: Usrname}
          }
        });
    

    Also, if no data is returned it does not mean bad credentials, but rather the item did not exist. You should use the exceptions which DynamoDB returns to you to provide more granular information rather than assuming credentials are wrong.

     if (!data.Item) {
          return res.status(404).json({ error: 'Item does not exist' });
        }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search