AWS Lambda Error – Runtime.ImportModuleError: Cannot find module ‘index’

 

AWS Lambda Error – Runtime.ImportModuleError: Cannot find module ‘index’

A diagnostic guide for resolving handler-file resolution failures in AWS Lambda caused by incorrect ZIP structure, missing files, permission issues, or runtime mismatches.





Problem

Your Lambda fails immediately upon invocation (before your code runs) with:

Node.js:

Runtime.ImportModuleError: Error: Cannot find module 'index'

Python:

[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'lambda_function'

This means Lambda attempted to bootstrap your function but could not locate the specific file defined in your Handler configuration.

Potential causes:

  • Wrong ZIP structure (files trapped inside a parent folder)
  • Permissions issues (file exists but is not readable by Lambda)
  • Handler path typo (configuring index.handler but uploading app.js)
  • Bundler output (Webpack/ESBuild moved the file to dist/)
  • Missing files (CI/CD excluded the source)

Clarifying the Issue

This error is not about NPM/Pip dependencies. It is about the entry point.

Lambda resolves your handler by looking at the specific path defined in your configuration: filename.method.

  • Config: index.handler → Lambda looks for index.js (or .mjs) at the root.
  • Config: src/app.handler → Lambda looks for src/app.js.

If the file is not exactly where the path points, the runtime crashes.


Steps at a Glance

  1. Confirm the handler string in Lambda configuration.
  2. Check CloudWatch for the exact missing path.
  3. Inspect ZIP structure (The #1 Cause).
  4. Verify File Permissions (The Silent Killer).
  5. Validate filenames and extensions (JS vs MJS vs PY).
  6. Review Bundler output (Dist vs Root).
  7. Re-deploy cleanly.

Detailed Steps

Step 1: Confirm the handler string.

Check what Lambda thinks it should run:

aws lambda get-function-configuration --function-name my-fn

Look for "Handler".

  • Node Example: "index.handler" means "Load index.js, run export handler."
  • Python Example: "lambda_function.lambda_handler" means "Load lambda_function.py, run function lambda_handler."

Step 2: Check CloudWatch for the missing file path.

Tail the logs to see where Lambda looked:

aws logs tail /aws/lambda/my-fn --since 5m

You will see a precise error:
Cannot find module '/var/task/src/index.js'

This reveals the absolute path Lambda tried to load. If your file is not at that exact location, it fails.


Step 3: Inspect the ZIP structure.

This is the most common cause.
Download and list the contents of your deployed artifact:

aws lambda get-function --function-name my-fn \
  --query 'Code.Location' --output text | xargs curl -o fn.zip

unzip -l fn.zip

Correct Structure (Flat): ✅

index.js
node_modules/
package.json

Incorrect Structure (Nested): ❌

my-project/             <-- The fatal extra folder
  index.js
  node_modules/

How this happens:

  • Windows: Right-clicking the folder and selecting "Compress to ZIP file" creates the nested structure. ❌
  • Fix: Select the files inside the folder, then compress them. ✅

Step 4: Verify File Permissions (The Silent Killer).

If index.js exists in the ZIP but you still get "Cannot find module," check permissions.

Lambda runs as a non-privileged user. If your local file was created with restricted permissions (e.g., 600 - read/write only by owner), Lambda cannot read it.

The Fix:
Ensure your build script sets generic read permissions before zipping:

chmod 644 index.js
chmod -R 755 .
zip -r function.zip .

Step 5: Validate filename + extension.

Node.js Runtimes:

  • index.js (CommonJS)
  • index.mjs (ESM)
  • Error: Using .ts (TypeScript) without compiling. Lambda cannot run TypeScript natively. ❌

Python Runtimes:

  • lambda_function.py
  • Error: Naming the file index.py but leaving the Handler config as lambda_function.lambda_handler. ❌

Step 6: Rebuild ZIP cleanly on correct OS family.

Use Docker to ensure your artifact is clean, has correct permissions, and uses Linux paths.

For Node.js:

docker run --rm -v "$PWD":/build -w /build amazonlinux:2023 \
  bash -c "npm ci && chmod -R 755 . && zip -r function.zip ."

For Python:

docker run --rm -v "$PWD":/build -w /build amazonlinux:2023 \
  bash -c "pip install -r requirements.txt -t . && chmod -R 755 . && zip -r function.zip ."

Step 7: Re-deploy and test.

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

aws lambda invoke --function-name my-fn --payload '{}' out.json

If the Exec format error or ImportModuleError persists, check Step 4 (Permissions) again.


Pro Tips

  • Match the Folder Logic:
    If your code is in src/handlers/user.js, update your Lambda Handler config to: src/handlers/user.handler. Do not try to force the ZIP to match the config; make the config match the reality.

  • Watch out for dist/:
    Tools like TypeScriptWebpack, and Esbuild often output to a dist or build folder. Ensure your deployment script zips the contents of dist, not the root of your project.

  • The "Export" Variant:
    If the error is handler is undefined (rather than "Cannot find module"), it means Lambda found the file, but your file didn't export the specific function name. Check for exports.handler = ... (CommonJS) or export const handler = ... (ESM).


Conclusion

Runtime.ImportModuleError is a loud, blocking error, but it is rarely complex. It is almost always a mismatch between where Lambda looks (Config) and where the file is (ZIP Structure).

By enforcing a flat ZIP structure, verifying Linux file permissions, and aligning your filenames with your runtime configuration, you ensure your Lambda can successfully bootstrap every time.


Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.

Comments

Popular posts from this blog

The New ChatGPT Reason Feature: What It Is and Why You Should Use It

Insight: The Great Minimal OS Showdown—DietPi vs Raspberry Pi OS Lite

Raspberry Pi Connect vs. RealVNC: A Comprehensive Comparison