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:
My credential and access key: (root user not created user)
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
Considering the error, There could be two possible problems here:
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.
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.
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.
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.