daydreamer
daydreamer

Reputation: 92169

Error: Cannot find module 'aws-sdk' in NodeJS AWS Lambda Function

I am trying to access S3 via aws-sdk in my lambda function.

import S3 from 'aws-sdk/clients/s3';

const s3 = new S3();
const { Contents: results } = await s3.listObjects({ Bucket: process.env.DOCUMENTS_BUCKET_NAME! }).promise()

I have also deployed it successfully using cdk deploy command. But when I test, I get the following error

2022-11-23T15:53:40.891Z    undefined   ERROR   Uncaught Exception  
{
    "errorType": "Runtime.ImportModuleError",
    "errorMessage": "Error: Cannot find module 'aws-sdk'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/index.mjs",
    "stack": [
        "Runtime.ImportModuleError: Error: Cannot find module 'aws-sdk'",
        "Require stack:",
        "- /var/task/index.js",
        "- /var/runtime/index.mjs",
        "    at _loadUserApp (file:///var/runtime/index.mjs:1000:17)",
        "    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)",
        "    at async start (file:///var/runtime/index.mjs:1200:23)",
        "    at async file:///var/runtime/index.mjs:1206:1"
    ]
}

As per the documentation, aws-sdk is always available in the runtime.

Does anyone know what am I doing wrong?

Thank you very much

Upvotes: 42

Views: 93524

Answers (7)

Leigh Mathieson
Leigh Mathieson

Reputation: 2038

If your lambda runtime is nodejs18.x or above my understanding is that AWS SDK v2 is not included in the runtime. (It was for nodejs16.x and below)

So, the best solution would be to switch to v3 SDK https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/

Or, as a workaround in the short term if you use webpack and usually exclude bundling aws-sdk with the following:

externals: {
    'aws-sdk': 'aws-sdk'
},

Then simply leave externals out of your webpack.config.js and it will be bundled, but will of course make your lambda larger so not ideal

Or use nodejs16.x or below in the short term

Upvotes: 46

Devashish Priyadarshi
Devashish Priyadarshi

Reputation: 175

In my case I had to switch to v3 sdk using this guide --> https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html#dynamodb-example-document-client-query

My code changed from

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

export const handler = async (event) => {
  var data = await DynamoDBClient.scan({ TableName: "dcn" }).promise();
  const response = {
    statusCode: 200,
    body: JSON.stringify(data),
  };
  return response;
};

to something like:

import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { QueryCommand, DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

export const handler = async (event) => {
  //var data = await DynamoDBClient.scan({ TableName: "dcn" }).promise();
  const command = new QueryCommand({
    TableName: "dcn",
    KeyConditionExpression:"id = :id",
    ExpressionAttributeValues: {":id":"xyz"},
    ConsistentRead: true,
  });
  const dbResp = await docClient.send(command);
  const response = {
    statusCode: 200,
    body: JSON.stringify(dbResp),
  };
  return response;
};

However it is not achiving the same effect as the older code, which was retrieving all the data from teh table while the new code just retrieves a particular key.

Upvotes: 5

Alex
Alex

Reputation: 9429

For those struggling with the Lambda upgrade from Node 16 to 18+, I kept getting this error until I did the following:

  1. Update Runtime from Node 16 to Node 20
  2. Update the code to import instead of require targeting the module that I needed import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses"; in my case (and other code changes as needed based on updated import)
  3. Rename the index.js file to index.mjs
  4. The tests kept failing, but after publishing the function they succeeded.

Obviously, this is pretty risky, publishing prior to successful test, so you should try this in a qa environment or with an unused function first.

Upvotes: -1

Nursultan Begaliev
Nursultan Begaliev

Reputation: 21

I also encountered this problem. I picked Node.js v18 when creating Lambda. It was giving me the same error. But changing the package to "@aws-sdk/*" new versions solved the problem.

Upvotes: 2

Andrés Carvajal
Andrés Carvajal

Reputation: 61

For those using serverless framework with esbuild, the plugin excludes 'aws-sdk' by default. In my case, I didn't downgrade to v16, I kept v18 and put an empty array in my serverless.yml

custom:
  esbuild:
    exclude: []

Upvotes: 6

daydreamer
daydreamer

Reputation: 92169

UPDATED LINK

Thank you @jarmod, I needed the following dependency

@aws-sdk/client-s3

My commit with the fix is available here

Upvotes: 15

syzygy0612
syzygy0612

Reputation: 37

What I did to fix this issue was to just downgrade my runtime settings from Node.js 18 to Node.js 16.x or below. After that, the test went successful.

Upvotes: 1

Related Questions