tailwindcss/packages
Benoît Rouleau a854b35bcf
Prevent @tailwindcss/upgrade from rewriting files inside node_modules when run from a workspace subpackage (#20329)
Fixes #20328.

## What changed

When `@tailwindcss/upgrade` is invoked from a subpackage of a workspace
(e.g. `pnpm --filter …` or `cd packages/foo && pnpm exec upgrade`), it
traverses `../../node_modules/…` and applies its v3 → v4 migration
transform (`@tailwind utilities;` → `@import 'tailwindcss/utilities'
layer(utilities);`) to files inside the installed `tailwindcss` package
itself — a self-referential import that later detonates as an infinite
CSS-resolution loop and reads like a "cache corruption" bug (matches the
report in #19726 / #20328).

Root cause: `globby`'s `isGitIgnored` only walks `.gitignore` files at
or below its `cwd`. When invoked from a subpackage, the workspace-root
`.gitignore` (which almost always lists `node_modules`) is never
consulted, and `../../node_modules/…` paths come back as **not**
ignored.

The fix anchors `isGitIgnored` at the git repository root instead of the
subpackage:

- New helper: `gitRoot(cwd)` in `src/utils/git.ts` — thin wrapper over
`git rev-parse --show-toplevel`.
- `analyze(stylesheets, { base })` in `src/codemods/css/analyze.ts` now
calls `isGitIgnored({ cwd: gitRoot(base) ?? base })`. Falls back to the
previous behavior when not inside a git repository or when `git` is
unavailable.

## Test

Added an integration test that reproduces the exact scenario: a pnpm
workspace with a subpackage that imports `tailwindcss/utilities.css`,
upgrade run from the subpackage, then asserts
`packages/css/node_modules/tailwindcss/utilities.css` still holds the
pristine `@tailwind utilities;` directive.

Verified the test fails on `main` and passes with this change.

The 415 existing upgrade unit tests still pass. Two npm-related snapshot
failures in `upgrade-errors.test.ts` (`half-upgraded v3 project to v4
(bun|npm)`) pre-exist this change — they're about newer npm's `npm
notice run` output that isn't in the snapshots, unrelated to what this
PR touches.


---

Edit by @RobinMalfait: going to run on all [ci-all] so we can make sure
it works on Windows as well.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2026-07-14 16:39:24 +00:00
..
@tailwindcss-browser 4.3.2 (#20281) 2026-06-29 10:10:00 -04:00
@tailwindcss-cli Lazy load @parcel/watcher (#20325) 2026-07-13 15:53:42 +02:00
@tailwindcss-node 4.3.2 (#20281) 2026-06-29 10:10:00 -04:00
@tailwindcss-postcss Fix weird character rendering on Windows with Japanese locale (#20318) 2026-07-14 17:04:20 +02:00
@tailwindcss-standalone Bump dependencies (#20300) 2026-07-02 11:45:49 +02:00
@tailwindcss-upgrade Prevent @tailwindcss/upgrade from rewriting files inside node_modules when run from a workspace subpackage (#20329) 2026-07-14 16:39:24 +00:00
@tailwindcss-vite 4.3.2 (#20281) 2026-06-29 10:10:00 -04:00
@tailwindcss-webpack 4.3.2 (#20281) 2026-06-29 10:10:00 -04:00
internal-example-plugin Prefix internal modules with internal-* (#14074) 2024-07-29 10:58:07 -04:00
tailwindcss Fix weird character rendering on Windows with Japanese locale (#20318) 2026-07-14 17:04:20 +02:00
tsconfig.base.json Improve debug logs (#15303) 2024-12-11 15:27:20 +01:00