excludeNodeDevDependencies includes all dev dependencies if serviceDir has symlinks
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- aws, javascript, node.js
Research direction
Start in packages/serverless/lib/plugins/package/lib/zip-service.js at the excludeNodeDevDependencies logic around lines 273-285, then run the attached repro.js to observe the symlink path mismatch. Verify that dependency paths remain valid under symlinked service directories, the doubled path and ENOENT are gone, and development dependencies are excluded from the Lambda zip.
Written by the indexing model from the issue text.
Description
Issue description
Environment
- Serverless Framework: 4.33.0
- Node.js: 22
- Build environment: AWS CodeBuild (source: CodeStar Connections / git-http)
Description
When deploying from AWS CodeBuild, all dev dependencies are bundled into the Lambda zip instead of being excluded. The root cause is that CodeBuild checks out source code into a directory path that contains symlink components, causing a path mismatch between what Serverless uses as serviceDir and what npm ls --parseable outputs.
The mismatch happens in two steps:
-
replace()silently fails. TheexcludeNodeDevDependencieslogic in zip-service.js usesString.replace()to strip theserviceDirprefix fromnpm ls --parseableoutput. However,serviceDirholds the symlink path whilenpm ls --parseableoutputs real (resolved) paths, becausechild_process.execresolves symlinks viachdir()+getcwd()on Linux. The prefix doesn't match, soreplace()returns the item unchanged — still a full absolute path like/codebuild/output/src1234/src/.../node_modules/loupe. -
path.joindoubles the path. Whenpath.join(serviceDir, item, 'package.json')receives an absolute path as the second argument, it doesn't treat it as a root — it strips the leading/and appends it toserviceDir, producing the doubled path seen in the error.
Observed error (from CodeBuild logs)
Unable to read the package.json file at
"/codebuild/output/src1234/src/.../component-name/codebuild/output/src1234/src/.../component-name/node_modules/loupe/package.json"
while processing dependencies for exclusion. Skipping this dependency.
Error: ENOENT: no such file or directory, open '...same doubled path.../package.json'
The path segment /codebuild/output/src1234/src/... appears twice — this is the doubled path. Because the package.json read fails with ENOENT, the dependency is skipped (not excluded), causing dev dependencies like loupe to be bundled.
Possible solution
Replace String.replace() with path.relative() when stripping the service directory prefix:
// Before (buggy)
const stripped = item.replace(path.join(serviceDir, path.sep), '')
// After (correct)
const stripped = path.relative(serviceDir, item)
path.relative() resolves through symlinks on both sides and always produces a correct relative path regardless of whether serviceDir or the npm output uses symlink vs real paths.
Reproduction
See attached repro.js, it creates original_folder with a node_modules tree, symlinks it as symlink_folder, and demonstrates that the buggy replace() fails while path.relative() succeeds.
Context
No response
- Dominant language
- JavaScript
- Stars
- 46.9k
- Forks
- 5.7k
- Avg merge
- 12h 57m
- Merged PRs (30d)
- 61
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from serverless/serverless
-
Difficulty 4/5 3-5 days Newbie friendliness 68/100
serverless/serverless#13889 · 1 comment · 1 assignee ·
-
serverless/serverless#13877 · 1 reaction · 1 assignee ·
-
bug
serverless/serverless#13876 · 1 assignee ·
-
bug cat/aws-iam
serverless/serverless#13872 · 1 assignee ·
-
cat/packaging enhancement
Difficulty 4/5 3-5 days Newbie friendliness 48/100
serverless/serverless#13701 ·
All issues in serverless/serverless
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
docToolchain/docToolchain#1705 ·
-
Timezone select lists one option per character; duplicate "Failed" reason; shared tracker popover id Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
nightscout/nocturne#1414 ·
-
bug v2
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
modelcontextprotocol/inspector#2458 · 1 comment ·
-
Mend: dependency security vulnerability status: needs triage 🕵️♀️
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
carbon-design-system/ibm-products#9907 ·