Skip to content

fix(scan): degrade gracefully when react-hooks-js plugin fails to load - #848

Merged
rayhanadev merged 1 commit into
mainfrom
ray/dhaka
Jun 16, 2026
Merged

fix(scan): degrade gracefully when react-hooks-js plugin fails to load#848
rayhanadev merged 1 commit into
mainfrom
ray/dhaka

Conversation

@rayhanadev

@rayhanadev rayhanadev commented Jun 16, 2026

Copy link
Copy Markdown
Member

Why

Fixes #833. When the optional react-hooks-js (React Compiler) plugin can't be imported in a user's environment, oxlint fails the entire config load — which dropped every curated react-doctor diagnostic too, leaving the scan with skippedChecks: ["lint"] and zero results. The oxlint error is multi-line, and the 200-char error preview truncated its plugin path mid-string (often right at …/node_modules/), so it read as react-doctor passing an invalid directory rather than a plugin that failed to load.

The reported "invalid directory path ending in /node_modules/" is therefore a truncation artifact — react-doctor resolves and passes the correct absolute entry file (verified across isolated/hoisted/workspace pnpm layouts); the real Error: reason was discarded by the 200-char slice.

Before:

Failed to parse oxlint output: Failed to parse oxlint configuration file.

  x Failed to load JS plugin: /path/to/project/node_modules/.pnpm/eslint-plugin-react-hooks@7.1.1_eslint@9.39.4_jiti@2.7.0_/node_modules/
No issues detected, but lint checks failed — results are incomplete.

After (verified via the diagnose() API against a project with a deliberately-broken eslint-plugin-react-hooks):

ok: true
skippedChecks: []                         # lint no longer fails outright
skippedCheckReasons: { "lint:partial":
  "React Compiler rules (react-hooks-js/*) skipped — eslint-plugin-react-hooks failed to
   load in this environment: Error: Cannot find module './cjs/...'. Other rules ran normally." }
rules: [ exhaustive-deps, rerender-functional-setstate, unused-file, ... ]   # curated rules still run

What changed

  • Graceful degradation (run-oxlint.ts + runners/oxlint/config.ts): detect a react-hooks-js plugin-load failure and retry once with that plugin + its compiler rules stripped (new internal disableReactHooksJsPlugin option), mirroring the existing adopted-extends fallback. Curated rules, dead-code, and environment checks all still run; the only casualty is the React Compiler rules, surfaced as a clear lint:partial note that includes oxlint's real underlying reason. Reported only after the retry succeeds, so a still-failing scan surfaces the original error untouched.
  • Readable error (constants.ts): bumped ERROR_PREVIEW_LENGTH_CHARS 200 → 600 so the full plugin path and the underlying Error: line survive instead of being cut at …/node_modules/.
  • Aligns with feat: native Rust+oxc React Compiler rules — drop eslint-plugin-react-hooks #627 (native Rust React Compiler port that drops this dependency) — this hardens against any jsPlugin load failure in the meantime.

Test plan

  • pnpm --filter @react-doctor/core test — 11 new tests (config drop + note detection) pass; full core suite green except 2 pre-existing check-*-env-file failures unrelated to this change (confirmed on the base tree).
  • pnpm --filter @react-doctor/core typecheck, react-doctor + @react-doctor/api typecheck — pass.
  • pnpm lint — exit 0; vp fmt --check — clean.
  • Manual end-to-end: diagnose() against a pnpm project with a broken eslint-plugin-react-hooksok: true, curated rules run, lint:partial note present (output above).

Open in Devin Review

Note

Low Risk
Targeted oxlint fallback and error-preview sizing in the lint runner; behavior change is narrower scans (no compiler rules) instead of total lint failure, with tests covering detection and config.

Overview
Fixes #833 when a broken eslint-plugin-react-hooks install used for optional React Compiler (react-hooks-js) rules would make oxlint reject the entire config, skipping all curated react-doctor lint and leaving skippedChecks: ["lint"].

The oxlint runner now detects that specific JS-plugin load failure (reactHooksJsPluginDropNote on OxlintOutputUnparseable output), retries once with disableReactHooksJsPlugin so only compiler rules are omitted, and surfaces a lint:partial note via onPartialFailure (including oxlint’s Error: line when present). The adopted-extends retry path is unchanged but uses the same buildConfig override shape.

Error previews for unparseable oxlint stdout grow from 200 → 600 characters so deep pnpm paths and the real failure reason are not truncated at …/node_modules/.

Tests cover config stripping and note detection; changeset bumps @react-doctor/core and react-doctor as patch.

Reviewed by Cursor Bugbot for commit 7266dcd. Bugbot is set up for automated code reviews on this repo. Configure here.

A broken/unimportable eslint-plugin-react-hooks made oxlint fail the
entire config load, which dropped every curated react-doctor diagnostic
(skippedChecks: ["lint"], zero results). The multi-line oxlint error was
also truncated to 200 chars, cutting the plugin path mid-string — often
at `…/node_modules/` — so it read as react-doctor passing an invalid
directory rather than a plugin that failed to import (issue #833).

Retry the scan once with the optional react-hooks-js plugin stripped so
the curated rules, dead-code, and environment checks still run; the
React Compiler rules are the only casualty, surfaced as a clear
`lint:partial` note carrying oxlint's real underlying reason. Bump the
unparseable-output preview 200 -> 600 so the full path and the `Error:`
line survive instead of being cut at `…/node_modules/`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pkg-pr-new

pkg-pr-new Bot commented Jun 16, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/eslint-plugin-react-doctor@848
npm i https://pkg.pr.new/oxlint-plugin-react-doctor@848
npm i https://pkg.pr.new/react-doctor@848

commit: 7266dcd

@github-actions

Copy link
Copy Markdown
Contributor

No React Doctor issues found. 🎉

Reviewed by React Doctor for commit 7266dcd.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@rayhanadev
rayhanadev merged commit 431e515 into main Jun 16, 2026
21 checks passed
@rayhanadev
rayhanadev deleted the ray/dhaka branch June 16, 2026 23:17
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.

pnpm project-local CLI can pass oxlint an invalid eslint-plugin-react-hooks directory path

1 participant