51

I keep getting this error in the aws-lambda console when uploading code from a zip file. I have tried uploading other zip files and they work correctly. The .js file is named "CreateThumbnail.js" in the zip file. I believe the handler is also named properly "CreateThumbnail.handler". the node_modules subdirectory is also setup. Anyone have any idea?

{
  "errorMessage": "Cannot find module 'CreateThumbnail'",
  "errorType": "Error",
  "stackTrace": [
  "Function.Module._resolveFilename (module.js:338:15)",
  "Function.Module._load (module.js:280:25)",
  "Module.require (module.js:364:17)",
  "require (module.js:380:17)"
  ]
}
2
  • Have you set "CreateThumbnail" as the Handler name in the "Change function configuration and role" section? Can you show the header of your function? Commented Jun 11, 2015 at 23:58
  • Did you make sure to zip the contents of the file, not the file itself? Commented Jul 22, 2015 at 17:38

14 Answers 14

25

The way I was able to get this to work was:

  1. Name the file exports.js
  2. Name the handler, within the file, exports.handler
  3. Set the handler in the lambda config to exports.handler
  4. Zip up only the contents of the folder, not the folder itself (as mentioned above) and rename the zip file exports.zip
Sign up to request clarification or add additional context in comments.

1 Comment

The actual name of the file is not really important. The key is to fully qualify the file and the path leading to it. My zip file has a directory named scripts, and inside it there are several files with exports.handler inside them. For Handler inside Lamdba's console, I specify, scripts/transforms.handler.
15

Ok, I did this myself, just make sure that you make the zip such that the .js file doesn't end up inside a folder, because AWS would unzip the file you upload and tries to find a .js file by the name of handler you gave, and if its inside a folder it won't help you.

2 Comments

Champion. So easy to trip over this if using OS X "Compress" that puts everything in a folder (as it should).
This saved me, as i tried to export the current code and it put everything into a folder when exporting so i thought i needed a folder when uploading as well
10

One possible problem is if you upload the lambda as a zip file created via PowerShell Compress-Archive. Compress-Archive has a bug which causes AWS to extract the files into a flat tree (no subdirectories), with backslashes in filenames:

enter image description here

1 Comment

One of the comments on that bug report has instructions for using the command line version 7zip instead of Compress-Archive. This worked for me
6

This exact error can show up if your zipped file(s) do not have world-wide read permission. (chmod -R ugo+r).

Check the file permissions before they are zipped. This is not emphasized enough unfortunately by AWS and it caused a lot of headaches for many.

2 Comments

I was using gulp to build and produce my zip file using the gulp-zip package, which produced this form of the issue. Only seemed to happen when it tried to compress it (the default), so using this option made it work for me: .pipe(zip('myfile.zip', { compress: false })). Thanks, I was pulling my hair out on this one for a while.
Scratch that..compress:false wasn't working, but gulp-zip was still the culprit. Manually zipping the same files worked.
5

If you are using AWS Lambda Layers you need to validate if your directory structure is on the needed structure for a layer:

For example for the moment.js node.js module you need the following structure:

aws-lambda-layer.zip
│ nodejs
│ nodejs/node_modules
└ nodejs/node_modules/moment

So to create a layer zip file with the correct structure we can use the following command on the root of our project:

mkdir -p nodejs && cp -r node_modules nodejs/ && zip -r aws-lambda-layer.zip nodejs

Comments

4

Some library files might not have global Read so lambda will not be able to read to content and build the content.

Make sure all files in node_modules are readable before packaging:

chmod -R +r node_modules

Then zip and upload.

Comments

2

This is the instruction from https://docs.aws.amazon.com/lambda/latest/dg/nodejs-package.html that I have followed and it works.

To update a Node.js function with dependencies

Open a command line terminal or shell. Ensure that the Node.js version in your local environment matches the Node.js version of your function.

Create a folder for the deployment package. The following steps assume that the folder is named my-function.

Install libraries in the node_modules directory using the npm install command.

npm install the_package_that_is_missing

Create a .zip file that contains the contents of your project folder. Use the r (recursive) option to ensure that zip compresses the subfolders.

zip -r function.zip .

Upload the package using the update-function-code command.

aws lambda update-function-code --function-name my-function --zip-file fileb://function.zip

Now your function is ready to run!

Comments

1

I had this problem on a custom module I had built that was in the node_modules dir. Everything ran fine in testing on my Win10 machine, but when uploaded I kept getting that same "Cannot find module 'modulename'" error.

It turns out that I had a mismatch; here's the package.json line from the module that couldn't be found:

"main": "./build/modulename.js",

and here's the actual filename:

Modulename.js

Case-sensitive; Windows isn't, linux (and thus AWS) is.

Comments

1

This is unrelated but google brought me here, so:

AWS will give you an error:

Unable to import module '<myfile>': Error

What was really happening for me, was that was requiring an unexisting JS file. The error is a bit misleading.

Comments

1

I ran into this same scenario, solved it by using these specific steps to create a Layer, then hook that up to the Lambda function.

  1. make a new empty directory:

    mkdir newdir && cd newdir
    
  2. install whatever npm things:

    npm install --save xyz
    
  3. make a directory skeleton that matches the expected Lambda structure for Node14 (there's a different structure for Node12, or various other languages; see https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html?icmpid=docs_lambda_help):

    mkdir -p nodejs/node14
    
  4. copy the "node_modules" directory into that newly made directory skeleton:

    cp -R node_modules nodejs/node14
    
  5. zip the whole thing up (name it whatever you want):

    zip -r custom-drivers-node14.zip nodejs
    
  6. from there, go to AWS console, Lambda, then "Layers" and create a new layer. In the dialog, upload your .zip file ("custom-drivers-node14.zip").

  7. finally, edit your Lambda function in AWS console, and add a new Layer – the interface might change, but as of now, this is under the main screen for a single function, then scroll way down to the bottom. Follow the "Add a layer" flow, choose the Layer you made, and then try your code.

One final note, this code structure worked:

const xyz = require('xyz');
exports.handler = async (event) => {
   xyz.doSomething();
}

Comments

0

AWS Lambda uses the name of the file and the name of the handler function, so if you defined your handler like this: exports.myHandler = function(event, context) in a file named index.js, your handler is index.myHandler.

1 Comment

if I need to use typescript, what else changes I need to do to use index.ts instead of index.js
0

This turned out to be a simple one for me.

I was getting, cannot create index. in my case, my main lambda file with the exports.handler in had to be called index.js

Try calling your main file CreateThumbnail.js

Comments

0

The tutorial tells you to include the following items in your zip file:

CreateThumbnail.js
/node_modules/gm
/node_modules/async

What it fails to consider is that there are dependencies of the two packages (gm, async) that also need to be part of the package.

So here's what you have to do:

  1. Change directory to node_modules folder in your project folder, and run the command 'npm install gm async'. This will install gm, async and all their dependencies in this folder.
  2. Now package the 'CreateThumbnail.js' file and the complete 'node_modules' folder into a zip file and upload it. It should work now.

So your complete package should look something like this:

CreateThumbnail.js
/node_modules/.bin
/node_modules/array-parallel
/node_modules/array-series
/node_modules/async
/node_modules/cross-spawn
/node_modules/debug
/node_modules/gm
/node_modules/isexe
/node_modules/lodash
/node_modules/lru-cache
/node_modules/ms
/node_modules/pseudomap
/node_modules/which
/node_modules/yallist

Comments

-1

File Name:
app.js
Lambda Function in "app.js":
exports.handler = function(event, context)...
Lambda Handler on Amazon Console:
app.handler ({app}.js + exports.{handler} = app.handler)

When you unzip the folder, you should see:
app.js
node_modules

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.