Skip to content

fix(devtools): opt-in lambda.keepNestedNodeModules ships nested node_modules in Lambda packages - #645

Merged
d-klotz merged 1 commit into
nextfrom
fix/devtools-keep-nested-node-modules
Sep 4, 2026
Merged

fix(devtools): opt-in lambda.keepNestedNodeModules ships nested node_modules in Lambda packages#645
d-klotz merged 1 commit into
nextfrom
fix/devtools-keep-nested-node-modules

Conversation

@d-klotz

@d-klotz d-klotz commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

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 first require then fails at Lambda init with Runtime.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, hubspot and salesforce functions all died at init for 33 minutes. readable-stream under multistream fails the same way. Earlier occurrences in the same app were worked around by declaring js-yaml, whatwg-url and uuid as root dependencies.

This PR adds lambda.keepNestedNodeModules: true. Default false, 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.
  • Applied at the five sites that emitted the blanket pattern: base-definition-factory (auth, user, health), integration-builder (integration functions, queue workers, DLQ processor), migration-builder (worker and router), admin-script-builder (executor and router). The app definition is threaded into createFunctionPackageConfig and createFunctionDefinitions.
  • infrastructure/README.md: option documented next to usePrismaLambdaLayer.

Test plan

  • Unit tests for the helper and for each builder: default keeps the blanket exclusion, opt-in removes it and keeps the scoped ones.
  • Full devtools suite.
  • Canary 2.0.0--canary.645.2234921.0 deployed 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, hubspot and salesforce__clockwork at init with Runtime.ImportModuleError: Cannot find module 'undici'. With the canary devtools and lambda.keepNestedNodeModules: true:

Function Probe Init
auth 401 on /api/integrations 1.38 s, no errors
hubspot 404 on an unknown route 1.42 s, no errors
salesforce__clockwork 200 on the webhook POST 1.28 s, no errors

Deployed salesforce__clockwork zip: 26 nested node_modules directories shipped, including jsforce/node_modules/undici (214 files) and multistream/node_modules/readable-stream (25 files); 0 nested @friggframework files; 0 @aws-sdk files anywhere; only the tracked .env.default and .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_modules fails to load the app definition (Cannot find module 'undici'); stripping only nested @friggframework, aws-sdk, @aws-sdk, @prisma and .prisma loads it, with jsforce resolving node_modules/jsforce/node_modules/undici.

Frigg CI: the build (22.x) failures are in cloudformation-discovery.test.js and vpc-builder.test.js plus 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 on next itself are red. The five suites covering this change pass (169 tests).

🤖 Generated with Claude Code

…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>
@d-klotz d-klotz added release Create a release when this pr is merged prerelease This change is available in a prerelease. labels Sep 3, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@netlify

netlify Bot commented Sep 3, 2026

Copy link
Copy Markdown

Deploy Preview for friggframework-org canceled.

Name Link
🔨 Latest commit 2234921
🔍 Latest deploy log https://app.netlify.com/projects/friggframework-org/deploys/6a99fd39431efa0008558389

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T23:07:42.496453Z 2234921 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +21 to +22
function keepsNestedNodeModules(appDefinition = {}) {
return appDefinition.lambda?.keepNestedNodeModules === true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@sonarqubecloud

sonarqubecloud Bot commented Sep 3, 2026

Copy link
Copy Markdown

@d-klotz
d-klotz merged commit 083f658 into next Sep 4, 2026
11 of 12 checks passed
@d-klotz
d-klotz deleted the fix/devtools-keep-nested-node-modules branch September 4, 2026 16:49
@seanspeaks

Copy link
Copy Markdown
Contributor

🚀 PR was released in v2.0.0-next.109 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prerelease This change is available in a prerelease. release Create a release when this pr is merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants