Skip to content

fix(oxc-plugin): stop installing a flaky oxlint-tsgolint and a vulnerable oxfmt - #269

Merged
rqbazan merged 3 commits into
mainfrom
chore/bump-tsgolint
Oct 18, 2026
Merged

rqbazan merged 3 commits into
mainfrom
chore/bump-tsgolint

Conversation

@rqbazan

@rqbazan rqbazan commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Summary

rr plugins add oxc hands new projects oxlint-tsgolint@^0.23.0. That version bundles a typescript-go whose macOS realpath breaks under concurrency, so rr tsc / rr check fail at random with TS2307 on modules that are installed. theme-toggle got the pin from here and hit the bug (withvariablelab/theme-toggle#18 has the full diagnosis).

It also hands them oxfmt@^0.51.0. oxfmt up to 0.66.0 pins tinypool@2.1.0, which has two critical advisories (GHSA-5gmw-xhrv-c9v3, GHSA-85c8-ppgw-ccpr). See oxfmt 0.73 below.

rr tsc → oxlint --type-aware --type-check
  tsgolint 0.23.0 (typescript-go c282336)
    module resolver → realpath(pnpm symlink)
      realpath_darwin.go: fcntl(fd, F_GETPATH, int(uintptr(&buf)))
        the buffer pointer passes through an int, so Go may move or reuse it
      → bad real path → TS2307

Upstream: microsoft/typescript-go#4060, fixed by microsoft/typescript-go#4178 (darwin only), reported against tsgolint in oxc-project/tsgolint#987.

 run-run/oxc-plugin/src/tool-versions.ts
-  oxfmt: { install: "^0.51.0" },
+  oxfmt: { install: "^0.73.0" },
-  "oxlint-tsgolint": { install: "^0.23.0" },
+  "oxlint-tsgolint": { install: "^7.0.2004" },

 run-run/oxc-plugin/package.json
   peerDependencies:
-    "oxfmt": ">=0.30.0",
+    "oxfmt": ">=0.67.0",
-    "oxlint-tsgolint": ">=0.15.0"
+    "oxlint-tsgolint": ">=0.24.0"
   devDependencies:
-    "oxlint-tsgolint": "0.23.0",
+    "oxlint-tsgolint": "0.25.0",

 package.json
-    "oxlint-tsgolint": "^0.23.0",
+    "oxlint-tsgolint": "^0.25.0",

Plus a patch changeset for @rrlab/oxc-plugin. The lockfile diff only touches oxlint-tsgolint entries.

The two peer floors exist only to warn

The new >=0.24.0 (tsgolint) and >=0.67.0 (oxfmt) floors exist only to flag broken or vulnerable versions. Every oxfmt from 0.30.0 to 0.66.0 pins the vulnerable tinypool 2.1.0. tsgolint 0.23.0 is the broken one (0.15–0.22 are fine but outdated; see below). Neither floor blocks an install: when a project updates @rrlab/oxc-plugin while still on one of those versions, pnpm 10 and npm 11 both install and print a peer warning (checked). Each floor also turns the existing tool-versions.test.ts (subset(install, peer)) into a regression test: it fails if install ever goes back to a broken or vulnerable range.

Why the ranges differ

  • install → ^7.0.2004. install() adds oxlint@^1.0.0 in the same step, and today that resolves to 1.88.0, which needs oxlint-tsgolint >=7.0.2003. With ^0.25.0 a new project would still get a broken peer pair: npm i fails with ERESOLVE, and pnpm prints a warning. Pairing 1.88.0 with 7.0.2004 installs with no warning. 7.0.2004 bundles the same typescript-go commit as 0.25.0 (2bd066d), and that commit has the fix. Decision 010 also says to pin 0.x tools to the latest on npm, which is now 7.0.2004. (The old ^0.23.0 has broken this peer pair ever since oxlint 1.75.)
  • devDependencies → 0.25.0. dx's own lockfile keeps oxlint 1.66.0 / 1.50.0, which accept >=0.22.1 / >=0.14.1. 0.25.0 is the newest 0.x and fixes the bug without touching oxlint. Bumping oxlint to 1.75+ (and tsgolint to 7.x with it) would also edit the root package.json and lockfile that the vulnerabilities PR is changing, so it is left out.
  • peer → >=0.24.0. 0.23.0 is the only tsgolint release with the bug (table below). With this floor, pnpm warns anyone still on 0.23.0, and the existing tool-versions.test.ts (subset(install, peer)) fails if install ever goes back to a broken range. 0.15–0.22 are fine but only pair with oxlint from before May (1.66 already needs >=0.22.1), so a plain floor beats >=0.15.0 <0.23.0 || >=0.24.0. Raising a peer floor is usually a breaking change. Here the tsgolint peer is optional, and both floors only make pnpm warn, so this ships as a patch.

The typescript-go submodule pinned by each tsgolint tag, compared on GitHub:

tsgolint typescript-go has a8b2a52 (bug) has 704847d (fix)
v0.22.1 — no no
v0.23.0 c282336 yes no
v0.24.0 c080da6 yes yes
v0.25.0 2bd066d yes yes
v7.0.2004 2bd066d yes yes

oxfmt 0.73

oxfmt pins tinypool to an exact version. Up to 0.66.0 that is 2.1.0, which both critical advisories cover (they are fixed in 2.1.2). 0.67.0–0.69.0 pin 2.1.2, and 0.73.0 (latest) pins 2.2.0. ^0.73.0 matches the oxfmt devDependency that dx#273 already set, and oxfmt has no peer link to oxlint or tsgolint. The peer goes from >=0.30.0 to >=0.67.0, the first oxfmt that pins a fixed tinypool (2.1.2).

Evidence

  • Regression test. Put install back to ^0.23.0 and the test fails:

    × oxlint-tsgolint: install range fits within the declared peer range
    AssertionError: install=^0.23.0 does not fit peer=>=0.24.0
    

    The same goes for oxfmt: put install back to ^0.51.0 and the test fails:

    × oxfmt: install range fits within the declared peer range
    AssertionError: install=^0.51.0 does not fit peer=>=0.67.0
    

    With this PR: Tests 8 passed (8).

  • The bug, in a project that gets the plugin's tools (theme-toggle), macOS arm64:

    Setup oxlint --type-aware --type-check failed
    oxlint 1.71.0 + tsgolint 0.23.0 8 / 60 (rr check: 4 / 40)
    same, GOMAXPROCS=1 0 / 100
    oxlint 1.71.0 + tsgolint 0.25.0 0 / 150 (rr check: 0 / 50)
    oxlint 1.88.0 + tsgolint 7.0.2004 (the new install pair) 0 / 100
  • The full install set in a fresh pnpm project (pnpm add -D oxlint@^1.0.0 oxfmt@<range> oxlint-tsgolint@<range>):

    Before (^0.51.0 / ^0.23.0) After (^0.73.0 / ^7.0.2004)
    Resolves to oxlint 1.88.0, oxfmt 0.51.0, tsgolint 0.23.0 oxlint 1.88.0, oxfmt 0.73.0, tsgolint 7.0.2004
    Peer check ✕ unmet peer oxlint-tsgolint@>=7.0.2003: found 0.23.0 clean
    tinypool 2.1.0 2.2.0
    pnpm audit 2 critical (.>oxfmt>tinypool) No known vulnerabilities
    oxlint --type-aware --type-check / oxfmt --check — run; TS2322 probe reported
  • dx itself: pnpm build && pnpm test && pnpm rr check pass. pnpm rr check failed 0 / 60 before the bump and 0 / 60 after (plus 0 / 30 after rebasing onto dx#272 and dx#273). dx never reproduced the bug, even before the bump, so this loop only shows that nothing broke.

CI can't show this bug. It runs on Ubuntu, and the broken code is darwin-only.

Merge Danger

Door: two-way

Reverting this PR and publishing a patch puts the old ranges back.

Blast Radius: new-installs

After a release, rr plugins add oxc installs tsgolint 7.x, which bundles a newer typescript-go, so new projects can see different type-check results than 0.23 gave. It also installs oxfmt 0.73, which can format some files differently than 0.51. Existing projects keep whatever they have. The only change for them is a pnpm peer warning if they are on tsgolint < 0.24 or oxfmt < 0.67, and that warning is the point of the floors.

🤖 Generated with Claude Code

https://claude.ai/code/session_01V4iz3teZoyUZW9nXnX9RQr

@changeset-bot

changeset-bot Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e1ced7f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@rrlab/oxc-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rqbazan
rqbazan force-pushed the chore/bump-tsgolint branch from 7aae95a to c01d85f Compare October 18, 2026 00:00
@rqbazan rqbazan changed the title fix(oxc-plugin): install oxlint-tsgolint 7 to stop flaky TS2307 on macOS fix(oxc-plugin): stop installing a flaky oxlint-tsgolint and a vulnerable oxfmt Oct 18, 2026
rqbazan and others added 3 commits October 17, 2026 19:06
oxlint-tsgolint 0.23.0 bundles a typescript-go whose macOS realpath
(fcntl F_GETPATH) can lose its buffer under concurrent module
resolution, so `rr tsc` fails at random with TS2307 on installed
modules (microsoft/typescript-go#4060, fixed in #4178).

- install range: ^0.23.0 -> ^7.0.2004, which also matches the
  >=7.0.2003 peer that current oxlint (installed as ^1.0.0) needs
- peer range: >=0.15.0 -> >=0.24.0, so the parity test rejects an
  install range that includes the broken release
- dx devDependencies: 0.23.0 -> 0.25.0, the fixed 0.x that still
  fits the locked oxlint 1.66

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4iz3teZoyUZW9nXnX9RQr
oxfmt up to 0.66.0 pins tinypool 2.1.0, which has two critical
advisories (GHSA-5gmw-xhrv-c9v3, GHSA-85c8-ppgw-ccpr), so every
project set up with `rr plugins add oxc` inherited them. 0.73.0 is
the latest oxfmt and pins tinypool 2.2.0, matching the devDependency
dx already uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4iz3teZoyUZW9nXnX9RQr
oxfmt below 0.67.0 pins tinypool 2.1.0 (two critical advisories).
A >=0.67.0 floor makes pnpm warn projects still on a vulnerable
oxfmt, and makes the TOOL_VERSIONS parity test reject an install
range that includes one, the same way the >=0.24.0 floor does for
oxlint-tsgolint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4iz3teZoyUZW9nXnX9RQr
@rqbazan
rqbazan force-pushed the chore/bump-tsgolint branch from f7e2247 to e1ced7f Compare October 18, 2026 00:06
@rqbazan
rqbazan merged commit cdb7137 into main Oct 18, 2026
11 checks passed
@rqbazan
rqbazan deleted the chore/bump-tsgolint branch October 18, 2026 04:09
@vland-bot vland-bot Bot mentioned this pull request Oct 18, 2026
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