Skip to content

fix(amplify-cli-core): detect packageManager field in package.json hierarchy#14628

Open
danrivett wants to merge 2 commits intoaws-amplify:devfrom
danrivett:cli-core/detect-packagemanager-field
Open

fix(amplify-cli-core): detect packageManager field in package.json hierarchy#14628
danrivett wants to merge 2 commits intoaws-amplify:devfrom
danrivett:cli-core/detect-packagemanager-field

Conversation

@danrivett
Copy link
Copy Markdown

Problem

The getPackageManager() function in amplify-cli-core doesn't detect the packageManager field in package.json, which is the standard corepack convention for specifying which package manager a project uses (e.g., "packageManager": "pnpm@10.17.0").

This causes failures in two scenarios:

  1. Corepack enforcement (Node.js 24+, where corepack is enabled by default): Amplify detects the wrong package manager based on lock files, then fails when corepack rejects the invocation. For example, running amplify build in a pnpm monorepo with "packageManager": "pnpm@10.x" produces:

    🛑 InvalidOverrideError: Received error [Error: Command failed with exit code 1: yarn --version
    This project is configured to use pnpm because <project-root>/package.json has a "packageManager" field]
    
  2. pnpm workspaces with no local lock file: When the Amplify project is in a subdirectory and no lock file is present locally (the lock file lives at the workspace root outside the Amplify directory), Amplify falls back to whichever package manager executable it finds on PATH (typically yarn), ignoring the packageManager field that specifies pnpm.

These failures will become increasingly common as corepack adoption grows and Node.js 24+ enables it by default.

Solution

Adds findPackageManagerFieldInHierarchy() that walks up the directory tree looking for a packageManager field in package.json files, mimicking corepack's own resolution behavior. When found, it takes precedence over lock file detection. If the specified package manager executable isn't found in PATH, it gracefully falls back to the existing detection logic.

Updated detection order

  1. Check if package.json exists (mandatory)
  2. Check for packageManager field in package.json hierarchy (new)
  3. Check if pnpm-lock.yaml is present + pnpm executable
  4. Check if yarn.lock is present + yarn executable
  5. Check if package-lock.json is present
  6. Check if yarn is in PATH
  7. Fallback to npm

Issue #, if available

Fixes #13931
Addresses #12001

Description of how you validated changes

  • 6 new unit tests added covering:
    • Detect pnpm from packageManager field in package.json
    • Detect npm from packageManager field in package.json
    • Detect yarn from packageManager field in package.json
    • Detect packageManager field from parent directory in hierarchy
    • packageManager field takes precedence over lock files
    • Falls back to lock file detection when packageManager executable not found
  • Full amplify-cli-core test suite passes (21 suites, 198 tests)
  • Manual testing with pnpm monorepo using corepack and "packageManager": "pnpm@10.x" in root package.json

Checklist

  • If this is a bug fix, the change doesn't introduce a breaking API change
  • If this is a new feature/enhancement, it was first discussed and approved in a GitHub issue
  • The change is covered by automated tests
  • The change passes all existing tests

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

…erarchy (aws-amplify#13931, aws-amplify#12001)

Add findPackageManagerFieldInHierarchy() that walks up the directory tree
looking for a packageManager field in package.json files, mimicking
corepack's resolution behavior. When found, it takes precedence over
lock file detection.

This fixes two failure modes:

1. In Node.js 24+ (where corepack is enabled by default), Amplify picks
   the wrong package manager based on lock files, then fails when
   corepack rejects the invocation (e.g. "Command failed with exit
   code 1: yarn --version" when packageManager specifies pnpm).

2. In pnpm workspaces where the Amplify project is in a subdirectory
   and no lock file is present locally (the lock file lives at the
   workspace root outside the Amplify directory), Amplify falls back
   to whichever package manager executable it finds on PATH (typically
   yarn), ignoring the packageManager field that specifies pnpm.
Add tests for the new findPackageManagerFieldInHierarchy() function
that detects the packageManager field in package.json hierarchy
(corepack convention for monorepos).

New test cases:
- Detect pnpm from packageManager field in package.json
- Detect npm from packageManager field in package.json
- Detect yarn from packageManager field in package.json
- Detect packageManager field from parent directory in hierarchy
- packageManager field takes precedence over lock files
- Falls back to lock file detection when packageManager executable not found
@danrivett danrivett force-pushed the cli-core/detect-packagemanager-field branch from 9159751 to a1e9296 Compare March 23, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

amplify always chooses the wrong package manager

1 participant