Expected Behavior
dist/handler.js should not be present in the published package for Node.js runtimes ≥ 14, as it causes the Lambda bootstrap to resolve the CJS entry point instead of dist/handler.mjs, preventing ESM user modules from loading correctly.
Actual Behavior
dist/handler.js is present in the published dist because tsc compiles src/handler.ts to dist/handler.js and it is never removed by the post-build script (scripts/update_dist_version.sh). When the Lambda bootstrap resolves the handler string node_modules/datadog-lambda-js/dist/handler.handler, it finds handler.js first and loads it as CJS. This causes loadSync → _tryRequireSync to be invoked, which does not attempt to load .mjs files, resulting in a failure when the user's module is ESM.
The root cause is in update_dist_version.sh:
This copies src/handler.mjs and src/handler.cjs into dist/, but dist/handler.js produced by tsc from src/handler.ts, is never cleaned up.
Steps to Reproduce the Problem
- Create a Lambda function with an ESM bundle (e.g.
index.mjs) and a package.json with "type": "module" at the task root.
- Set the Lambda handler string to
node_modules/datadog-lambda-js/dist/handler.handler (standard Datadog handler redirect).
- Deploy and invoke the Lambda on Node.js 18 or above.
Specifications
- Datadog NPM version: 12.138.0 (latest at time of writing
dist/handler.js confirmed present)
- Node version: 18.x and above (also reproduced on 24.x)
Stacktrace
{
"errorType": "Error",
"errorMessage": "require() of ES Module /var/task/index.mjs from /var/task/node_modules/datadog-lambda-js/dist/runtime/user-function.js not supported.",
"stack": [
"Error [ERR_REQUIRE_ESM]: require() of ES Module /var/task/index.mjs ...",
" at _tryRequireSync (.../datadog-lambda-js/dist/runtime/user-function.js)",
" at _loadUserAppSync (.../datadog-lambda-js/dist/runtime/user-function.js)",
" at loadSync (.../datadog-lambda-js/dist/runtime/user-function.js)",
" at Object.<anonymous> (.../datadog-lambda-js/dist/handler.js)"
]
}
Workaround: Manually delete dist/handler.js after npm install in the Dockerfile (as documented in #295). This was flagged in 2022 with a promise to remove the file after Node 12 EOL, but it remains in the package today.
Suggested fix: Add rm dist/handler.js to update_dist_version.sh after the cp src/handler.* dist/ step, since the .mjs and .cjs variants now fully cover all supported runtimes.
Expected Behavior
dist/handler.jsshould not be present in the published package for Node.js runtimes ≥ 14, as it causes the Lambda bootstrap to resolve the CJS entry point instead ofdist/handler.mjs, preventing ESM user modules from loading correctly.Actual Behavior
dist/handler.jsis present in the published dist becausetsccompilessrc/handler.tstodist/handler.jsand it is never removed by the post-build script (scripts/update_dist_version.sh). When the Lambda bootstrap resolves the handler stringnode_modules/datadog-lambda-js/dist/handler.handler, it findshandler.jsfirst and loads it as CJS. This causesloadSync→_tryRequireSyncto be invoked, which does not attempt to load.mjsfiles, resulting in a failure when the user's module is ESM.The root cause is in
update_dist_version.sh:cp src/handler.* dist/This copies
src/handler.mjsandsrc/handler.cjsintodist/, butdist/handler.jsproduced bytscfromsrc/handler.ts, is never cleaned up.Steps to Reproduce the Problem
index.mjs) and apackage.jsonwith"type": "module"at the task root.node_modules/datadog-lambda-js/dist/handler.handler(standard Datadog handler redirect).Specifications
dist/handler.jsconfirmed present)Stacktrace
Workaround: Manually delete
dist/handler.jsafternpm installin the Dockerfile (as documented in #295). This was flagged in 2022 with a promise to remove the file after Node 12 EOL, but it remains in the package today.Suggested fix: Add
rm dist/handler.jstoupdate_dist_version.shafter thecp src/handler.* dist/step, since the.mjsand.cjsvariants now fully cover all supported runtimes.