yarnpkg / yarn

The 1.x line is frozen - features and bugfixes now happen on https://github.com/yarnpkg/berry
https://classic.yarnpkg.com
Other
41.37k stars 2.72k forks source link

Yarn v1.22.21 introduces new issue when using Corepack #9015

Open TooTallNate opened 7 months ago

TooTallNate commented 7 months ago

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": "pnpm@8.3.1", "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": "pnpm@8.3.1", "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@pnpm@8.3.1". 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.

aduh95 commented 7 months ago

It also breaks actions/setup-node: https://github.com/actions/setup-node/issues/899#issuecomment-1819151595

arcanis commented 7 months ago

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 🤔

arcanis commented 7 months ago

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).

RDIL commented 7 months ago

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.

TooTallNate commented 7 months ago

In my case, this happened when running tests against fixtures that specify different packageManager versions. The tests themselves are run through yarn though.

mikelpr commented 7 months ago

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/setup-node@v3.0.0 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": "yarn@3.2.4". 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.
arcanis commented 7 months ago

There's something strange I need help understand. This message is only supposed to show up if all of those conditions are true:

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.

mikelpr commented 7 months ago

sorry @arcanis disregard my case - for some reason yarn@3.2.4 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

LittleHendrix commented 7 months ago

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.

john-ciq commented 7 months ago

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 yarn@1.22.19 --force
## NOTE: 1.22.20 FAILS
## TODO: Uncomment the next line to see a failure on 1.22.20
# RUN npm install -g yarn@1.22.20 --force
## NOTE: 1.22.21 FAILS
## TODO: Uncomment the next line to see a failure on 1.22.21
# RUN npm install -g yarn@1.22.21 --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": "yarn@3.4.1", "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
RDIL commented 7 months ago

@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

jeanbaptistedebize commented 7 months ago

Downgrade to yarn@1.22.19 work for me, npm install -g yarn@1.22.19

john-ciq commented 7 months ago

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 yarn@3.4.1, 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": "yarn@3.4.1". 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 yarn@1.22.19 -f
## Run the next line for failure (using yarn 1.22.20)
## RUN npm i -g yarn@1.22.20 -f

WORKDIR /usr/src
RUN echo '{ "packageManager": "yarn@3.4.1", "scripts": { "test": "echo hi" } }' > package.json
RUN yarn test
arcanis commented 7 months ago

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": "yarn@3.4.1", "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).

john-ciq commented 7 months ago

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!

Aghassi commented 7 months ago

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@pnpm@8.6.11". 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.

john-ciq commented 7 months ago

@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.

Aghassi commented 7 months ago

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.

john-ciq commented 7 months ago

@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.

Aghassi commented 7 months ago

Yeah that's the solution we came to also sadly

arcanis commented 7 months ago

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?

TooTallNate commented 7 months ago

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.

Aghassi commented 7 months ago

@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?

Aghassi commented 7 months ago

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.

arcanis commented 7 months ago

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": "yarn@1.22.21" 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.

TooTallNate commented 7 months ago

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 yarn@1.22.19 manually after setup-node, since that was the path of least resistance compared to the suggested solution of setting "packageManager": "yarn@1.22.21" 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 😂 )

maxwihlborg commented 7 months ago

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?

ranisalt commented 5 months ago

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.

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

Eveeifyeve commented 4 months ago

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

Eveeifyeve commented 4 months ago

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.

AlessandroVol23 commented 2 months ago

I have the sam issue on a node 12 project and the package.json doesn't even define a package manager. I see the following error:

error This project's package.json defines "packageManager": "yarn@pnpm@8.15.6". However the current global version of Yarn is 1.22.22.

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.
arcanis commented 2 months ago

yarn@pnpm@8.15.6

Corepack doesn't make up this string (outside of the yarn@pnpm part, which seems a formatting glitch), you have to have a package.json with the packageManager field set to this value somewhere up your directory tree. If not in your current folder, then one of its parents.

RDIL commented 2 months ago

Maybe it would be best if this check states the exact path of the package.json it's found it in?

Eveeifyeve commented 2 months ago

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.

But for Yarn I really shouldn't have to do this setup but I guess it's temporarily.

tranvansang commented 2 months ago

God!! too many unnecessary troubles with yarn 2:

and now, this corepack enable issue.

In my case, switching back to npm solves all these problems. After many years of being a fan of yarn, now I give up!!

andrew-aladjev commented 1 month ago

I've received this error while trying to test yarn upgrade and downgrade:

yarn set version stable
yarn set version classic # Downgrade using stable version
yarn set version stable # Upgrade using classic version

The problem is actually that latest classic release checks packageManager value and it doesn't like it, so upgrade using classic version fails. So for now such upgrade is not possible.

The solution for me is to use some old stable version instead of classic.

lawrenceong commented 4 weeks ago

The latest node:20-alpine contains yarn 1.22.22, so this issue is appearing for us now.

The package.json file contains the following entry:

"packageManager": "yarn@4.2.2"

When we build an image, the final image do not include the .yarn directory, so yarn run (or yarn <scriptname>) no longer works and results in the corepack error. The yarn directory itself is 3.4M. Since we want to keep the image lean, we've since replaced yarn run with npm run for the built image.

aduh95 commented 4 weeks ago

@lawrenceong consider setting SKIP_YARN_COREPACK_CHECK=0 in the env.