yarn
yarn copied to clipboard
Yarn v1.22.21 introduces new issue when using Corepack
Seems like https://github.com/yarnpkg/yarn/commit/a84723816a81908214a5eb69fbf55fec0326b35a introduces a false-positive when the packageManager
field specifies a package manager that is not yarn
.
This dockerfile demonstrates the issue:
FROM node:20-alpine
RUN npm i -g yarn -f
WORKDIR /usr/src
RUN echo '{ "packageManager": "[email protected]", "scripts": { "test": "echo hi" } }' > package.json
RUN yarn test
$ docker build -t yarn-test .
[+] Building 1.0s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 211B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:20-alpine 0.6s
=> [1/5] FROM docker.io/library/node:20-alpine@sha256:cb2301e2c5fe3165ba2616591efe53b4b6223849ac0871c138f56d5f7ae8be4b 0.0s
=> CACHED [2/5] RUN npm i -g yarn -f 0.0s
=> CACHED [3/5] WORKDIR /usr/src 0.0s
=> CACHED [4/5] RUN echo '{ "packageManager": "[email protected]", "scripts": { "test": "echo hi" } }' > package.json 0.0s
=> ERROR [5/5] RUN yarn test 0.4s
------
> [5/5] RUN yarn test:
#8 0.346 error This project's package.json defines "packageManager": "yarn@[email protected]". However the current global version of Yarn is 1.22.21.
#8 0.346
#8 0.346 Presence of the "packageManager" field indicates that the project is meant to be used with Corepack, a tool included by default with all official Node.js distributions starting from 16.9 and 14.19.
#8 0.346 Corepack must currently be enabled by running corepack enable in your terminal. For more information, check out https://yarnpkg.com/corepack.
------
I would expect yarn to ignore this check in the case of packageManager
not being yarn.
It also breaks actions/setup-node: https://github.com/actions/setup-node/issues/899#issuecomment-1819151595
I would expect yarn to ignore this check in the case of
packageManager
not being yarn.
Why is yarn run
being used on a pnpm project? It seems a bug, same as we don't support running npm run
on a Yarn project 🤔
Also note that this also kinda matches how Corepack itself works: calling any pnpm command on a Yarn project yields an error, and the other way around (unless COREPACK_ENABLE_STRICT=0
is explicitly set).
Yeah, if a project states its preferred package manager, and that isn’t Yarn, it shouldn’t work in the first place. This probably shouldn’t have been shipped in a semver-patch release, but still.
In my case, this happened when running tests against fixtures that specify different packageManager
versions. The tests themselves are run through yarn though.
this happened to me on a project that uses yarn 3.2.4 during the build with github actions (running yarn --frozen-lockfile
after actions/[email protected]
and actions/checkout@v3
). I suspect it'd fail on my computer too if I had yarn v1.22.1
error This project's package.json defines "packageManager": "[email protected]". However the current global version of Yarn is 1.22.21.
Presence of the "packageManager" field indicates that the project is meant to be used with Corepack, a tool included by default with all official Node.js distributions starting from 16.[9](https://github.com/SkyAlert/iot-types/actions/runs/6949340645/job/18907230292#step:4:10) and 14.19.
Corepack must currently be enabled by running corepack enable in your terminal. For more information, check out https://yarnpkg.com/corepack.
Error: Process completed with exit code 1.
There's something strange I need help understand. This message is only supposed to show up if all of those conditions are true:
- There is no
yarnPath
setting - There is no
YARN_IGNORE_PATH
in the environment - Corepack isn't installed
- The project defines a
packageManager
field - The
packageManager
field is something else than 1.x
My assumption writing this check was that if we didn't error, then Yarn 1.x would silently perform the install, not 3.x nor 4.x. Did I make a mistake? Can you check your logs before the 1.22.21 release and confirm the installs were performed by Yarn 3.x / 4.x? If it was working well, then something is off in the condition that we definitely should understand and fix.
sorry @arcanis disregard my case - for some reason [email protected] was set as the packageManager in the package.json but there was no .yarn dir at all. possibly I used it and rolled back to classic yarn and it didn't care about the packageManager field before 1.22.21 and only did checks on the .yarn dir
I've had same issues with both projects that has a packageManager
field defined, as well as projects without one 🤷♂️
And after reverting back to v1.22.1
everything worked as expected.
This dockerfile allowed me to test different versions of yarn in order to find the version at which this new issue presented. It appears to be 1.22.20
## To run this Docker container:
## docker build -t yarntest . && docker run --rm -it yarntest
## Record yarn version
RUN mkdir -p /usr/src
RUN echo -n "yarn version initial: " >> /usr/src/yarn.version && yarn -v >> /usr/src/yarn.version
## Run corepack
RUN corepack enable
RUN echo -n "yarn version after corepack enable: " >> /usr/src/yarn.version && yarn -v >> /usr/src/yarn.version
RUN corepack prepare yarn@stable --activate
RUN echo -n "yarn version after corepack activate: " >> /usr/src/yarn.version && yarn -v >> /usr/src/yarn.version
## Globally install yarn
##
## NOTE: 1.22.19 SUCCEEDS
RUN npm install -g [email protected] --force
## NOTE: 1.22.20 FAILS
## TODO: Uncomment the next line to see a failure on 1.22.20
# RUN npm install -g [email protected] --force
## NOTE: 1.22.21 FAILS
## TODO: Uncomment the next line to see a failure on 1.22.21
# RUN npm install -g [email protected] --force
RUN echo -n "yarn version after global install: " >> /usr/src/yarn.version && yarn -v >> /usr/src/yarn.version
## Make the package.json
WORKDIR /usr/src
RUN echo '{ "packageManager": "[email protected]", "scripts": { "test": "echo Yarn test works && yarn -v" } }' > package.json
## Run "yarn install" to invoke yarn
RUN echo -n "using yarn version: " >> /usr/src/yarn.version && yarn -v >> /usr/src/yarn.version
## NOTE: This next comment is on one line so that the entire content will be displayed in the console on error
## This will FAIL if yarn is 1.22.20+; in this case, comment out the next two lines and set the ENTRYPOINT to /bin/sh for diagnostic access
RUN yarn install
## Print the versions
ENTRYPOINT /bin/cat yarn.version
@john-ciq if you have corepack enabled you shouldn't add Yarn globally. In that case, the issue is happening because yarn
from npm global installs is ahead (or behind? I can't remember exactly how path environment variables work) of corepack's binaries in $PATH
Downgrade to [email protected] work for me,
npm install -g [email protected]
In that case, the issue is happening because yarn from npm global installs is ahead (or behind? I can't remember exactly how path environment variables work) of corepack's binaries in $PATH
Thanks for pointing that out, @RDIL. I included corepack as that was what my particular use case was. I removed corepack and can still reproduce the issue. yarn 1.22.19 works when packageManager specifies [email protected], but yarn 1.22.20 fails with this message:
0.451 warning package.json: No license field
0.453 error This project's package.json defines "packageManager": "[email protected]". However the current global version of Yarn is 1.22.20.
0.453
0.453 Presence of the "packageManager" field indicates that the project is meant to be used with Corepack, a tool included by default with all official Node.js distributions starting from 16.9 and 14.19.
0.453 Corepack must currently be enabled by running corepack enable in your terminal. For more information, check out https://yarnpkg.com/corepack.
Dockerfile to reproduce:
FROM node:20-alpine
## To run this Docker container:
## docker build . -t yarntest && docker run --rm -it yarntest
## Run the next line for success (using yarn 1.22.19)
RUN npm i -g [email protected] -f
## Run the next line for failure (using yarn 1.22.20)
## RUN npm i -g [email protected] -f
WORKDIR /usr/src
RUN echo '{ "packageManager": "[email protected]", "scripts": { "test": "echo hi" } }' > package.json
RUN yarn test
Running your example with the --progress=plain
flag, it shows the situation I described, where yarn test
was accidentally performed by 1.22, not the version you had defined in your packageManager
field:
docker build . --no-cache --progress=plain -t yarntest && docker run --rm -it yarntest
#7 [4/5] RUN echo '{ "packageManager": "[email protected]", "scripts": { "test": "echo hi" } }' > package.json
#7 DONE 0.3s
#8 [5/5] RUN yarn test
#8 0.513 yarn run v1.22.19
#8 0.520 warning package.json: No license field
#8 0.530 $ echo hi
#8 0.537 hi
#8 0.537 Done in 0.03s.
#8 DONE 0.6s
That's why we have the warning: if Corepack isn't enabled, the packageManager
field will be silently ignored. In that case, either remove it, add Corepack, or set SKIP_YARN_COREPACK_CHECK=0
to disable the check (not recommended).
Thanks for the help and explanation, @arcanis.
I did have to set COREPACK_ROOT as well as SKIP_YARN_COREPACK_CHECK, as per https://github.com/yarnpkg/yarn/blob/1.22-stable/src/cli/index.js#L292C21-L292C33
But all is well now, thank you!
Can a fix be added to not opt people into this change by default? We have users that use yarn
in a monorepo and those packages are not yet part of a global pnpm
workspace. Thus, we are seeing
error This project's package.json defines "packageManager": "yarn@[email protected]". However the current global version of Yarn is 1.22.21.
Presence of the "packageManager" field indicates that the project is meant to be used with Corepack, a tool included by default with all official Node.js distributions starting from 16.9 and 14.19.
Corepack must currently be enabled by running corepack enable in your terminal. For more information, check out https://yarnpkg.com/corepack.
Which is a false error because the projects are not part of that workspace and are being treated as such.
@Aghassi, that situation seems similar to mine. If possible, you may be able to avoid the error by setting both COREPACK_ROOT=0
and YARN_SKIP_COREPACK_CHECK=0
(the values won't matter, but the environment variables both need to exist for this workaround.
Sorry, but that's not scalable nor an acceptable answer for an entire engineering org to adopt just to revert back to functionality that we had yesterday. It's nice there is an eject, but this shouldn't be needed. It's a breaking change in my book and should have been on a separate major version of Yarn. 1.22 was end of life and we were under the impression it was not receiving any other changes. Users should be pinned in our org but we may also have folks who accidentally upgrade their yarn and end up in this situation.
@Aghassi It does seem like a breaking change, though I can't speak for yarn contributors or maintainers.
The solution I came to was to force an install of yarn 1.22.19.
Yeah that's the solution we came to also sadly
I still find it odd that you define a packageManager
field but don't care that it's actually respected. Why do you have it at all?
There has already been at least two [1][2] explanations of situations where this change broke existing setups. I'm not sure why you are confused.
@arcanis in our case it's because we are mid migration from Yarn to PNPM and for the PNPM world we care about it being respected. Anything that's yarn based is not in the PNPM workspace yet and therefore should not care about any package manager declarations above the project. Here's my use case:
/- package.json <-- PNPM workspace with package manager defined / - web | |- package.json <-- yarn workspace with no package manager defined that will eventually join the PNPM workspace above. But today is considered unrelated
Does that make sense?
The other workaround we do have is to set the .yarn/release folder with a pinned version of yarn for all projects that need to avoid this problem for now.
Anything that's yarn based is not in the PNPM workspace yet and therefore should not care about any package manager declarations above the project.
It makes sense, but in that case you should declare "packageManager": "[email protected]"
inside your web/package.json
folder. Corepack (and the Yarn check) will then leverage the proper packageManager
depending on the closest package.json
.
There has already been at least two [1][2] explanations of situations where this change broke existing setups. I'm not sure why you are confused.
I got examples of invalid setups which were already performing differently depending on whether Corepack was installed or not, unbeknown to their users. Reporting these situations is the very purpose of the error, so I see it more as a bugfix than a breaking change. I understand it can be a fine line (hence why we added the SKIP_YARN_COREPACK_CHECK
flag to at least give you the option to opt-out of the bugfix), but remember that the packageManager
field is still marked experimental, and we can afford to be a little more aggressive in bugfixes if it only affects its users.
What I'm looking for in this thread are use cases where the project is properly setup (ie either "packageManager": "1.22.something"
, or no packageManager
field at all in both the project and its parent folders), and the error is still thrown.
I'm not sure I agree that the scenarios described would be considered invalid setups. They are sub-packages that are not meant to be considered part of the workspace. The yarn check is IMO overly presumptive in assuming that everything is part of the workspace.
The breaking change aspect is annoying because our CI randomly broke one day and we had to go digging as to where the error was even coming from (the error URL in the message saved the day, so thanks for that). More annoying is that actions/setup-node
doesn't allow configuration of which version of yarn is installed.
At the end of the day, we opted for installing [email protected]
manually after setup-node
, since that was the path of least resistance compared to the suggested solution of setting "packageManager": "[email protected]"
in all the necessary sub-packages, or setting the skip env var for every relevant test. Make of that what you will.
I think at the very least yarn should bail on this check if the detected packageManager
field does not begin with yarn@
.
(I do appreciate the XKCD reference though. That one's a classic 😂 )
There's something strange I need help understand. This message is only supposed to show up if all of those conditions are true:
I don't know if it has been discussed previously (if so just ignore) but I looked into the code a little bit. It seems like the new findPackageManager
function introduced in https://github.com/yarnpkg/yarn/commit/a84723816a81908214a5eb69fbf55fec0326b35a might cause issues.
It looks like it previously would have thrown an error in main and exited silently before the packageManager check, since it wouldn't find the .yarn-metadata.json
file in repositories not using yarn https://github.com/yarnpkg/yarn/blob/v1.22.21/src/config.js#L690?
What I'm looking for in this thread are use cases where the project is properly setup (ie either
"packageManager": "1.22.something"
, or nopackageManager
field at all in both the project and its parent folders), and the error is still thrown.
This error throws on yarn 4.0.2 and a dependency uses another package manager to run its scripts. In my case, we depend on abort-controller-es5 and its postinstall script is npm run postinstall:commonjs && npm run postinstall:esm
, so when I run yarn install
it complains that I should not use npm because the root project is configured to use yarn.
This may be an issue with corepack and not yarn, I'm not sure
This issue should be brought up since it effecting me to use my package manager bun
and it still happens and I don't know what to do now just downgrade and corepack disable
For anyone who is the having the same issue I would enable it and then do yarn set version 1.22.0
and then disable to fix the issue temporarily.