Skip to content

fix(fix): run a pinned Yarn Berry through corepack when the yarn on PATH is classic - #54

Merged
lucasbraum merged 1 commit into
mainfrom
fix/yarn-berry-corepack
Oct 10, 2026
Merged

lucasbraum merged 1 commit into
mainfrom
fix/yarn-berry-corepack

Conversation

@lucasbraum

Copy link
Copy Markdown
Collaborator

What and why

On a repository whose package.json pins "packageManager": "yarn@4.x" (any Yarn 2 or later) while the global yarn is classic 1.x, or there is none, uptide fix and uptide verify failed to install: Yarn stopped with "This project's package.json defines packageManager yarn@4.7.0. However the current global version of Yarn is 1.22.22". The same failure the pack-test job had on tldraw's ground truth (#53), fixed there with corepack in CI.

The installer used by fix and verify (packages/core/src/fix/managers/availability.ts) now:

  • Detects a pinned Yarn 2+ that the yarn on PATH cannot run: classic 1.x, another version than the pin, or no yarn at all (needsCorepack). A Berry on PATH at the pinned version is used as before.
  • Runs it through corepack when corepack is available: the same install as corepack yarn install --immutable --mode=skip-build, with COREPACK_ENABLE_DOWNLOAD_PROMPT=0 and COREPACK_ENABLE_AUTO_PIN=0 (throughCorepack). Nothing on the user's machine changes outside corepack's own cache: no corepack enable, no shim, no rewrite of packageManager. Every later install in the run (updateArgs, the plain install) goes through the same route (PackageManager.via).
  • Exits 2 before cloning when corepack is missing (PACKAGE_MANAGER_UNAVAILABLE, raised by run.ts before any clone), with the exact command:
    This repository pins yarn@4.7.0 (packageManager), but the yarn on PATH is 1.22.22 and corepack is not available to run the pinned version. Nothing was cloned or installed.
    Next: corepack enable
    
  • Respects COREPACK_NPM_REGISTRY from the environment (it passes through to the corepack call as it is) and names it only when corepack could not fetch the pinned version, together with the manual activation command.

docs/troubleshooting.md gains "Yarn 4 says the global Yarn is 1.x", and the "Package manager not available" section points to it. packs/tooling/truth.ts (ground-truth installs for pack test) is unchanged; CI handles that with corepack enable since #53.

How it was verified

Unit tests in availability.test.ts, against a new fixture fixtures/repos/yarn-berry-pinned (synthetic: pins yarn@4.7.0, Berry lockfile, node-modules linker, nothing installed):

  • detection: pinned Berry with no yarn, with classic 1.22.22, with Berry 4.6.0 → corepack; with Berry 4.7.0 → not; classic and pnpm repositories → never;
  • command selection: corepack yarn install --immutable --mode=skip-build, prompt off, via: 'corepack', updateArgs prefixed with yarn;
  • the probe sequence (yarn --version, corepack --version, corepack yarn --version) and that corepack enable is never run;
  • corepack missing → exit-2 error with Next: corepack enable; corepack unable to fetch → message with COREPACK_NPM_REGISTRY and the activation command (and the registry hint absent when corepack is simply missing); a corepack yarn at the wrong version → PACKAGE_MANAGER_VERSION.

pnpm lint, pnpm typecheck, pnpm docs:links, the private-material guard, core (928 tests) and CLI (350 tests) pass. One unrelated test (check/progress.test.ts, worker-event forwarding) failed once while the suite shared the machine with the build, and passed three times in isolation.

Checklist

  • Tests for the change (a bug fix starts with a failing test)
  • pnpm lint && pnpm typecheck && pnpm test pass
  • README and docs updated if behavior changed
  • Changeset added if a user would notice (pnpm changeset): patch
  • No new dependency, or it was agreed in an issue
  • No private code, names or paths in fixtures, tests or docs
  • The rules in CONTRIBUTING.md ("Rules that do not bend") still hold

🤖 Generated with Claude Code

https://claude.ai/code/session_018u9b3Pp5H68DdYZGp5Qg1U


Generated by Claude Code

…ATH is classic

A repository that pins yarn@2 or later in packageManager failed to install under fix and
verify when the global yarn was classic 1.x (or absent): Yarn stopped with "the current
global version of Yarn is 1.22.22". The same failure CI had on tldraw's ground truth.

- availability.ts: needsCorepack says when the pinned Berry cannot run through the yarn on
  PATH (classic, another version, or none); throughCorepack runs the same install as
  `corepack yarn ...` with COREPACK_ENABLE_DOWNLOAD_PROMPT=0 and COREPACK_ENABLE_AUTO_PIN=0,
  without `corepack enable` or any change to the user's global config; COREPACK_NPM_REGISTRY
  from the environment passes through. A matching Berry on PATH is used as it is.
- Without corepack the run stops before cloning (PACKAGE_MANAGER_UNAVAILABLE, exit 2) with
  "Next: corepack enable"; when corepack cannot fetch the pinned version, the message names
  COREPACK_NPM_REGISTRY and the manual activation command.
- manager.ts: PackageManager.via marks the corepack route; updateArgs prefixes `yarn` then.
- fixtures/repos/yarn-berry-pinned: a synthetic repository pinning yarn@4.7.0 with a Berry
  lockfile, used by the unit tests for detection, command selection and the messages.
- docs/troubleshooting.md: "Yarn 4 says the global Yarn is 1.x".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018u9b3Pp5H68DdYZGp5Qg1U
Signed-off-by: Lucas Braum <lucas.braum@deskfy.io>
@lucasbraum
lucasbraum marked this pull request as ready for review October 10, 2026 01:45
@lucasbraum
lucasbraum merged commit c502cc8 into main Oct 10, 2026
8 checks passed
@lucasbraum
lucasbraum deleted the fix/yarn-berry-corepack branch October 10, 2026 01:46
@uptide-release uptide-release Bot mentioned this pull request Oct 10, 2026
lucasbraum pushed a commit that referenced this pull request Oct 10, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and publish to npm
yourself or [setup this action to publish
automatically](https://github.com/changesets/action#with-publishing). If
you're not ready to do a release yet, that's fine, whenever you add more
changesets to main, this PR will be updated.


# Releases
## uptide@0.6.1

### Patch Changes

- [#56](#56)
[`c64ba2c`](c64ba2c)
Thanks [@lucasbraum](https://github.com/lucasbraum)! - The HTML report's
light theme uses `#6A675F` for dimmed text (5.1:1 on the page
background,
was 4.2:1, below WCAG AA's 4.5:1), and the package's homepage is
https://uptide-dev.github.io/docs.

- [#54](#54)
[`c502cc8`](c502cc8)
Thanks [@lucasbraum](https://github.com/lucasbraum)! - `fix` and
`verify` install a repository that pins Yarn 2 or later in
`packageManager` even
when the `yarn` on PATH is classic 1.x or absent: the pinned version
runs through corepack
(`corepack yarn install ...`, download prompt off) without enabling
corepack or changing
anything on your machine outside corepack's cache. Before, Yarn stopped
the run with "the
current global version of Yarn is 1.22.22". When corepack is missing,
the run stops before
cloning with exit code 2 and the command to run (`corepack enable`);
when corepack cannot
fetch the pinned version, the message names `COREPACK_NPM_REGISTRY` for
corporate mirrors.

Co-authored-by: uptide-release[bot] <338861287+uptide-release[bot]@users.noreply.github.com>
lucasbraum added a commit that referenced this pull request Oct 10, 2026
…st (#59)

## What and why

Closes #58.

`forwards real workspace worker events without serializing the callback`
(`packages/core/src/check/progress.test.ts`) imported the shared
`packages/core/dist/index.js`. `pnpm build` runs tsup with `clean:
true`, which deletes and rewrites `dist/`. A build running at the same
time as the test (the PR #54 case: lint and build in parallel) can
remove the bundle while the child process imports it.

This was not a timing problem. There are no sleeps or fixed timeouts,
and event order is fine: progress messages and the result share one
worker port, so they arrive in order. Both failures I reproduced are the
same `ERR_MODULE_NOT_FOUND`:

```
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/user/uptide/packages/core/dist/index.js' imported from /home/user/uptide/packages/core/[eval1]
```

The test exists to run the **built** worker (`dist/worker.js`), which
the source-based suite never runs, so it still needs a real build. It
now builds its own copy:
- tsup with the package's own config, `--no-dts --no-sourcemap` (about 1
s), into a fresh `mkdtemp` directory under
`packages/core/node_modules/`. Being inside the package lets the
bundle's bare imports (`ts-morph`, …) resolve.
- The directory is removed in `afterAll`.

No published code changes, so there is no changeset.

## How it was verified

Each loop is 50 runs of `vitest run src/check/progress.test.ts -t
'forwards real workspace'` on a 4-core machine:

| Load | Before | After |
|---|---|---|
| Busy loop on every core | 0 / 50 failed | not rerun (time was never
the cause) |
| `pnpm build` and `pnpm lint` looping in parallel | **2 / 50 failed
(4%)**, both `ERR_MODULE_NOT_FOUND` | **0 / 50 failed** |

At a 4% rate, 0 failures in 50 runs could still happen by chance (about
13%), so I also checked the mechanism directly. With
`packages/core/dist` deleted, the original test fails with the same
error and the new one passes.

## Checklist

- [x] Tests for the change (with `dist/` removed: the old test fails,
the new one passes)
- [x] `pnpm lint && pnpm typecheck && pnpm test` pass (core 927 passed /
15 skipped, cli 350 passed)
- [x] README and docs updated if behavior changed (no behavior change)
- [x] Changeset added if a user would notice (test-only, none)
- [x] No new dependency (tsup is already a devDependency of
`@uptide/core`)
- [x] No private code, names or paths in fixtures, tests or docs
- [x] The rules in CONTRIBUTING.md ("Rules that do not bend") still hold

Not changed here: other tests that read a package's `dist/` (for example
`packages/cli/src/list-registry.test.ts` and `telemetry/sender.test.ts`)
could hit the same race when a build runs alongside them.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01EmiChUUtLdjbg6mNzKqVep

---
_Generated by [Claude
Code](https://claude.ai/code/session_01EmiChUUtLdjbg6mNzKqVep)_

Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
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.

1 participant