fix(devtools): opt-in lambda.keepNestedNodeModules ships nested node_modules in Lambda packages - #645
Conversation
…modules in Lambda packages Every function package excluded node_modules/**/node_modules/**. npm nests a package only when the root copy cannot satisfy the dependant, so the exclusion made packages resolve whatever was hoisted and dropped a package entirely when the root copy was a dev dependency; the first require then failed at Lambda init with Runtime.ImportModuleError (jsforce's undici 8, multistream's readable-stream 3). Apps opt in with lambda.keepNestedNodeModules: true. The default is unchanged. With the flag, nested copies of @friggframework/*, aws-sdk, @aws-sdk/* and, when the Prisma layer is used, @prisma/* and .prisma stay excluded because the app's single core, the runtime and the layer provide them. Applied at the five sites that emitted the blanket pattern. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
Claude Code Review
Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.
Tip: disable this comment in your organization's Code Review settings.
✅ Deploy Preview for friggframework-org canceled.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 223492161e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| function keepsNestedNodeModules(appDefinition = {}) { | ||
| return appDefinition.lambda?.keepNestedNodeModules === true; |
There was a problem hiding this comment.
Add the new Lambda option to the app-definition schema
When an app definition containing this documented opt-in is passed through @friggframework/schemas's validateAppDefinition, validation rejects it as an unknown property because packages/schemas/schemas/app-definition.schema.json allows only lambda.scopedEnvironment and sets additionalProperties: false on lambda. Add keepNestedNodeModules as a boolean schema property so schema-valid workflows can enable the new packaging behavior.
Useful? React with 👍 / 👎.
|
|
🚀 PR was released in |



Summary
Every Lambda package excludes
node_modules/**/node_modules/**. npm nests a package only when the root copy cannot satisfy the dependant, so the exclusion makes packages resolve whatever is hoisted, and it drops a package entirely when the root copy is a dev dependency. The firstrequirethen fails at Lambda init withRuntime.ImportModuleError.Seen today on the clockwork-recruiting-integrations dev stack: jsforce 3.10.24 needs undici 8, npm nested it under jsforce because serverless-esbuild and osls pin undici 6 and 7 at the root, the package dropped it, and the
auth,hubspotandsalesforcefunctions all died at init for 33 minutes.readable-streamundermultistreamfails the same way. Earlier occurrences in the same app were worked around by declaringjs-yaml,whatwg-urlanduuidas root dependencies.This PR adds
lambda.keepNestedNodeModules: true. Defaultfalse, no behavior change for existing apps (ADR-027's no-behavior-change-on-upgrade bar). When set, function packages ship nested node_modules as npm resolved them, except nested copies of@friggframework/*,aws-sdk,@aws-sdk/*and, with the Prisma layer,@prisma/*and.prisma: the app's single core, the Lambda runtime and the layer provide those.Changes
infrastructure/domains/shared/utilities/nested-node-modules.js: the option read and the pattern list.createFunctionPackageConfigandcreateFunctionDefinitions.infrastructure/README.md: option documented next tousePrismaLambdaLayer.Test plan
2.0.0--canary.645.2234921.0deployed to the clockwork dev stack with the flag set and the undici and readable-stream root declarations removed (lockfile restored to the nested placements): every Lambda boots, see below.Canary verification (clockwork-recruiting-integrations, dev, 2026-09-03 23:33Z)
Before the fix the same lockfile killed
auth,hubspotandsalesforce__clockworkat init withRuntime.ImportModuleError: Cannot find module 'undici'. With the canary devtools andlambda.keepNestedNodeModules: true:/api/integrationsDeployed
salesforce__clockworkzip: 26 nestednode_modulesdirectories shipped, includingjsforce/node_modules/undici(214 files) andmultistream/node_modules/readable-stream(25 files); 0 nested@friggframeworkfiles; 0@aws-sdkfiles anywhere; only the tracked.env.defaultand.env.example. Size 37 → 42 MB compressed, 138 → 145 MB unzipped, about 183 MB with the Prisma layer against the 250 MB limit.Local reproduction of the packaging rule on a production-only install of that lockfile: stripping every nested
node_modulesfails to load the app definition (Cannot find module 'undici'); stripping only nested@friggframework,aws-sdk,@aws-sdk,@prismaand.prismaloads it, with jsforce resolvingnode_modules/jsforce/node_modules/undici.Frigg CI: the
build (22.x)failures are incloudformation-discovery.test.jsandvpc-builder.test.jsplus the 10-minute step timeout. Neither suite imports a file changed here, both fail identically on a local checkout of this branch, and the last four CI runs onnextitself are red. The five suites covering this change pass (169 tests).🤖 Generated with Claude Code