Skip to content

npm config get cache fails with EBADDEVENGINES when requiring newer npm versions in devEngines #1553

Description

@patrik-csak

Description: setup-node fails immediately if the initial npm version doesn't satisfy devEngines.packageManager.version

If a package requires a specific version of Node.js and a specific version of npm, but the built-in npm version is different than the package's required npm version, setup-node fails immediately (at npm config get cache) with EBADDEVENGINES, before there is a chance to install a different version of npm

For example, if my package requires Node.js v22.x and npm v11.10+, npm config get cache fails because Node.js v22 ships with npm v10

Action version: v6.4.0

Platform:

  • Ubuntu
  • macOS
  • Windows

Runner type:

  • Hosted
  • Self-hosted

Tools version:

  • Node.js: 22.22.2
  • npm: 10.9.7

Repro steps:

  1. Configure package.json

    {
    	"engines": {
    		"node": "^22"
    	},
    	"devEngines": {
    		"packageManager": {
    			"name": "npm",
    			"version": "^11.10.0"
    		}
    	}
    }
  2. Call setup-node

    jobs:
      setup-node:
        runs-on: 'ubuntu-latest'
        steps:
          - uses: actions/checkout@v6.0.2
    
          # fails
          - uses: actions/setup-node@v6.4.0
            with:
              node-version-file: package.json
    
          # never runs
          - run: npm --global install npm@^11.10.0
  3. setup-node fails

    Run actions/setup-node@v6.4.0
    with:
      node-version-file: package.json
      check-latest: false
      token: ***
      package-manager-cache: true
    
    Resolved package.json as ^22
    Found in cache @ /opt/hostedtoolcache/node/22.22.2/x64
    
    Environment details
    node: v22.22.2
    npm: 10.9.7
    yarn: 1.22.22
    
    Detected npm as the package manager from package.json's packageManager field. Auto caching has been enabled for npm. If you want to disable it, set package-manager-cache input to false
    /opt/hostedtoolcache/node/22.22.2/x64/bin/npm config get cache
    npm error code EBADDEVENGINES
    npm error EBADDEVENGINES The developer of this package has specified the following through devEngines
    npm error EBADDEVENGINES Invalid devEngines.packageManager
    npm error EBADDEVENGINES Invalid semver version "^11.10.0" does not match "10.9.7" for "packageManager"
    npm error EBADDEVENGINES {
    npm error EBADDEVENGINES   current: { name: 'npm', version: '10.9.7' },
    npm error EBADDEVENGINES   required: { name: 'npm', version: '^11.10.0' }
    npm error EBADDEVENGINES }
    

Expected behavior:

I expect setup-node to succeed so that I can immediately install a version of npm required by my project

Actual behavior:

setup-node fails before I can install a version of npm required by my project


My use case:

My app requires Node.js v22, so I declare that in package.json.engines:

{
	"engines": {
		"node": "^22"
	}
}

I want to enforce min-release-age, so I add it to .npmrc:

min-release-age = 1

min-release-age was added in npm v11.10.0, so I require npm v11.10+ in package.json.devEngines:

{
	"devEngines": {
		"packageManager": {
			"name": "npm",
			"version": "^11.10.0"
		}
	}
}

This is basically the same as #1410, but #1410 was closed with a workaround that only works in certain situations. I created this issue to explain my use case, and my project's constraints, which I think should be pretty standard: require the Maintenance LTS version of Node.js and a newer minimum version of npm

#1410 was closed with this workaround:

The reliable workaround is to specify a Node version in setup-node that already includes the npm version your devEngines.packageManager requires. This ensures the npm version matches your project’s requirements from the start.

This is only possible if your Node.js version is flexible and happens to ship with an npm version that satisfies the project's requirements


Related: #529

Activity

  1. v-chiranjib-swain commented on May 21, 2026

    @v-chiranjib-swain

    Hi @patrik-csak ,
    Thank you for creating this issue. We will investigate it and provide feedback as soon as we have some updates.

  2. v-jitenderpalsingh commented on May 27, 2026

    @v-jitenderpalsingh
    Contributor

    Hello @patrik-csak,
    Thank you for the detailed report and for clearly explaining your use case.
    The workflow is failing because your project requires npm@^11.10.0 in devEngines.packageManager.version, while the installed npm version is 10.9.7. As a result, npm exits with EBADDEVENGINES, causing the action to fail early.
    As a possible workaround, could you try setting onFail: "warn" under devEngines.packageManager. According to the npm docs, devEngines supports an onFail field, and setting it to warn should cause the version mismatch to be treated as a warning instead of an error, which may allow the workflow to continue so you can install the required npm version in a later step.

    Example package.json:

    {
      "engines": {
        "node": "^22"
      },
      "devEngines": {
        "packageManager": {
          "name": "npm",
          "version": "^11.10.0",
          "onFail": "warn"
        }
      }
    }
    

    After that, you can install the required npm version in the workflow once setup-node completes successfully.
    Also, for additional reference, you can refer to nodejs/node/issues/62425, which is related to npm installation behavior on Node v22.22.2.
    Please let us know if the issue persists after trying the above update.

  3. v-jitenderpalsingh commented on Jun 8, 2026

    @v-jitenderpalsingh
    Contributor

    Hello @patrik-csak, just a gentle follow-up on this issue. If you have any updates or need further assistance, please let us know.

  4. v-jitenderpalsingh commented on Jun 15, 2026

    @v-jitenderpalsingh
    Contributor

    Hello @patrik-csak, just checking in on this issue. If you have any updates or still need assistance, please let us know.

  5. patrik-csak commented on Jun 15, 2026

    @patrik-csak
    Author

    As a possible workaround, could you try setting onFail: "warn" under devEngines.packageManager.

    I don’t think that’s an acceptable workaround. I think it defeats the purpose of devEngines for this use case.

    Also, for additional reference, you can refer to nodejs/node/issues/62425, which is related to npm installation behavior on Node v22.22.2.

    It’s not clear to me what that issue has to do with this one

  6. patrik-csak commented on Jun 16, 2026

    @patrik-csak
    Author

    For now I’m disabling caching:

    steps:
      - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version-file: package.json
          package-manager-cache: false
    
      - shell: bash
        run: |
          version="$(jq --raw-output .devEngines.packageManager.version package.json)"
          npm --global install npm@$version
          echo "npm: $(npm --version)"
  7. v-jitenderpalsingh commented on Jun 19, 2026

    @v-jitenderpalsingh
    Contributor

    Hello @patrik-csak, Thank you for your feedback.
    Yes disabling caching is a possible workaround to prevent the workflow from failing because the caching step internally runs npm config get cache, which triggers npm's devEngines validation against the currently installed npm version, causing the EBADDEVENGINES error. Also if needed, you can add caching at a later step. You can refer to actions/cache examples for implementation.

    Example workflow to add caching:

    steps:
      - uses: actions/checkout@v6
    
      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: package.json
          package-manager-cache: false
    
      - name: Upgrade npm
        run: npm install -g npm@^11.10.0
    
      - name: Get cache dir
        id: npm-cache-dir
        run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
    
      - name: Implement cache
        uses: actions/cache@v5
        with:
          path: ${{ steps.npm-cache-dir.outputs.dir }}
          key: node-cache-${{ runner.os }}-${{ runner.ARCH }}-npm-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            node-cache-${{ runner.os }}-${{ runner.ARCH }}-

    We will consider this as a feature request and depending on community interest and engagement, we'll explore the possibility of incorporating a fix directly into setup-node.

  8. added
    feature requestNew feature or request to improve the current logic
    and removed
    bugSomething isn't working
    on Jun 19, 2026
  9. removed their assignment
    on Jun 19, 2026
  10. patrik-csak commented on Jun 19, 2026

    @patrik-csak
    Author
  11. yafanasiev commented on Jul 1, 2026

    @yafanasiev

    We hit this issue when working on a bit unconventional monorepo setup. Root of the repository is managed via pnpm, with devEngines set properly. But one of the subfolders is still on NPM, has it's own separate package.json and separate workflow with setup-node pointed to it:

              node-version-file: "subfolder/package.json"
              cache-dependency-path: "subfolder/package-lock.json"
    

    action is able to properly parse and install version of the NodeJS from it, but then npm config get cache runs in the root of the repository - where pnpm is used so we get EBADDEVENGINES.
    Maybe it would be possible to specify the workdir for the cache config command?

  12. v-jitenderpalsingh commented on Jul 17, 2026

    @v-jitenderpalsingh
    Contributor

    Hello @yafanasiev, Thank you for sharing your use case.
    We tried reproducing with the configuration you shared but weren't able to trigger a workflow failure. Could you please provide a link to a failing workflow run or minimal repro link so we can investigate further?

    In the meantime, you can set package-manager-cache: false and use actions/cache separately to handle caching manually.

  13. v-jitenderpalsingh commented on Sep 17, 2026

    @v-jitenderpalsingh
    Contributor

    Hi @yafanasiev, just a gentle follow-up regarding your earlier comment. Are you still experiencing the reported behavior? If so, could you please share a minimal reproduction or a failing workflow run to help us investigate? Thank you.

  14. 43081j commented on Sep 17, 2026

    @43081j

    can you fix this? 👀

    ideally you'd just read the devEngines.packageManager in this action, realise it is non-default, then install it before dealing with caching.

    people then also don't need a hand rolled npm i -g npm@11 (or 12).

    really, this action should just do it based on whats in devEngines IMO

    this problem leaves people with 2 options:

    1. Turn off caching, get the right npm version
    2. Turn off error-level devEngines, get the wrong npm version and lose minAge/allowScripts

    neither is ideal obviously. this is a bug rather than a feature i would say

  15. eran132 commented on Sep 27, 2026

    @eran132

    @v-jitenderpalsingh here's a minimal public repro, since you asked for one.

    Repro: eran132/runner-images@test/devengines contains only the package.json from the original report plus a workflow. Run, ubuntu-24.04, 10 attempts per combination:

    setup-node caching result
    v6.4.0 / v7.0.0 default (package-manager-cache: true) fails 20/20
    v6.4.0 / v7.0.0 cache: npm fails 20/20
    v6.4.0 / v7.0.0 package-manager-cache: false succeeds 20/20
    [command]/opt/hostedtoolcache/node/22.23.2/x64/bin/npm config get cache
    npm error EBADDEVENGINES Invalid semver version "^11.10.0" does not match "10.9.8" for "packageManager"
    Error: Cache folder paths are not retrieved for npm with cache-dependency-path =
    

    Cause: supportedPackageManagers.npm.getCacheFolderPath in src/cache-utils.ts runs npm config get cache in the workspace. npm 10.x (the version bundled with Node 22) checks devEngines even for this read-only config command and exits 1. It fails before the user gets a chance to upgrade npm in a later step. npm 11.19 (Node 24) doesn't fail here.

    Possible fix: I tried a few variants in node:22 (npm 10.9.9) and node:24 (npm 11.19.0) containers, 10 runs each, with and without a project .npmrc containing cache=...:

    command (run in the project dir) npm 10.9 honours project .npmrc cache=
    npm config get cache exit 1 –
    npm config get cache --force exit 0 (devEngines mismatch printed as warnings) yes
    npm_config_force=true npm config get cache exit 0 yes
    npm config get cache --no-engine-strict exit 1 –
    same command run from outside the project dir exit 0 no, returns ~/.npm

    Adding --force to that one command seems like the smallest fix that keeps the current semantics, including a project-level .npmrc cache override. The same --force check also passed 60/60 on the hosted runner. Running the command from another directory also avoids the error, but it would silently ignore the project's .npmrc.

    I'm happy to open a PR with this change and a unit test if the approach works for you.

  16. v-jitenderpalsingh commented on Sep 30, 2026

    @v-jitenderpalsingh
    Contributor

    Hello @eran132,

    Thank you for providing the reproduction and sharing your detailed findings.

    We have confirmed that the issue is reproducible when the installed npm version does not satisfy the requirement in devEngines.packageManager, causing npm config get cache to fail with EBADDEVENGINES.

    To clarify, we were asking for an example of the monorepo setup with pnpm at the root and npm in a subfolder to help us investigate that specific scenario further.

    We appreciate your help in investigating this issue.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestNew feature or request to improve the current logic

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions