19

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

uzluisf
  • 2,586
  • 1
  • 9
  • 27
daydreamer
  • 87,243
  • 191
  • 450
  • 722
  • Based on the fact that your code is calling the legacy `listObjects` method rather than `listObjectsV2` and is using the `.promise()` feature, you appear to be trying to use JavaScript SDK v2, so `const AWS = require('aws-sdk'); const s3 = new AWS.S3();` – jarmod Nov 23 '22 at 16:27
  • Or use SDK v3 as documented [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/index.html). – jarmod Nov 23 '22 at 16:28

4 Answers4

22

If your lambda runtime is nodejs18.x my understanding is that SDK v2 is not included in the runtime.

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

Leigh Mathieson
  • 1,658
  • 2
  • 17
  • 25
  • 1
    using nodejs16.x fix my problem. But I don't know why. Obviously, the same code worked at nodejs18.x before. do runtime nodejs18.x remove SDK v2 now? – FerntreeGuy Jun 17 '23 at 13:32
  • Link to AWS Blog about this change regarding Node 16 vs Node 18 and its supported AWS SDK version: https://aws.amazon.com/blogs/compute/node-js-18-x-runtime-now-available-in-aws-lambda/ – Jake Waggoner Jun 23 '23 at 19:16
5

UPDATED LINK

Thank you @jarmod, I needed the following dependency

@aws-sdk/client-s3

My commit with the fix is available here

daydreamer
  • 87,243
  • 191
  • 450
  • 722
1

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.

Leigh Mathieson
  • 1,658
  • 2
  • 17
  • 25
syzygy0612
  • 29
  • 2
0

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: []