Solving AWS Lambda's "Cannot find module 'index'" Problem

Recently I returned to an old Node app that runs on AWS Lambdas. When they work well, Lambdas are a wonderful piece of serverless technology, allowing applications to scale up and down as required. I finished my changes, prepped the app for deployment, uploaded it, then stumbled into a small AWS Lambda pitfall entirely of my own making, but one surprisingly tough to debug, given the cryptic error message when I tried to access the Lambda in the browser:

undefined ERROR Uncaught Exception {
  "errorType": "Runtime.ImportModuleError",
  "errorMessage": "Error: Cannot find module 'index'\nRequire stack:\n- /var/runtime/index.mjs",
  "stack": [
    "Runtime.ImportModuleError: Error: Cannot find module 'index'",
    "Require stack:",
    "- /var/runtime/index.mjs",
    " at _loadUserApp (file:///var/runtime/index.mjs:1087:17)",
    " at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)",
    " at async start (file:///var/runtime/index.mjs:1282:23)",
    " at async file:///var/runtime/index.mjs:1288:1"
  ]
}

At first glance, this was baffling. Why was it looking for index.mjs as an entry point to the lambda? My app had always had an index.js, or a handler.js. Had AWS silently updated Lambda to mandate ES modules? Was my trusty old Node.js app suddenly outdated overnight? Possible, but as I chased cryptic and misleading error messages deeper and deeper down a google/stack overflow rabbit hole, I was getting dangerously close to "is there a bug in the compiler?" territory. As usual, the real problem sat not in the code, but firmly between the chair and the keyboard.

What's Actually Happening?

When a Lambda is invoked, it's effectively loading a zipped folder of code into its container, then executing it. This can be handled automatically when granting the right IAM access to frameworks like Serverless, or you can manually upload a zip to S3 and link that to your Lambda. The latter approach is much more manual and time-consuming, but on this project I was working within a pair of particularly-restrictive IAM handcuffs, so was stuck with the manual approach. In either case, an archive of your project is ultimately linked to your Lambda.

The runtime then expects your application's entry file (index.js, handler.js, etc) to be located at the root of your zip archive. If, like me, you accidentally zip the entire folder containing your app (instead of just its contents), Lambda won't find your entry point. It panics and gives you the confusing message about a missing index module, defaulting to the assumption index.mjs should be in use.

The error is a red herring, as Lambda doesn't need an index.mjs. It's just AWS's way of saying, "I can't find your entry file at the root of the zip."

The Fix

Make sure you zip your project's contents, not the folder itself:

What I had done:

zip -r function.zip myLambdaFunctionFolder

What I should have done:

cd myLambdaFunctionFolder
zip -r ../function.zip .

I uploaded the correct zip, linked it to my Lambda, and normal service was resumed. Hopefully, this saves someone else the 30 minutes of head-desking it cost me!


IPC Berlin Speaker

IPC Munich 2025

In October 2025, I'll be speaking at the International PHP Conference in Munich. I'll be talking about Modern PHP Features You’re Probably Not Using (But Should Be). Expect real-world examples, practical takeaways, and a deep dive into cleaning your code while making your life easier!

Get your ticket now and I'll see you there!


Share This Article

Related Articles


More