Skip to content

fix(react-doctor): skip empty patterns before knip runs (#149)#150

Draft
aidenybai wants to merge 1 commit intomainfrom
cursor/fix-knip-empty-pattern-149-d5f6
Draft

fix(react-doctor): skip empty patterns before knip runs (#149)#150
aidenybai wants to merge 1 commit intomainfrom
cursor/fix-knip-empty-pattern-149-d5f6

Conversation

@aidenybai
Copy link
Copy Markdown
Member

Closes #149.

Problem

react-doctor reports × Dead code detection failed (non-fatal, skipping). Expected pattern to be a non-empty string and silently drops the entire dead-code step.

The error originates inside knip: every entry, project, ignore, and plugin pattern is funneled through picomatch, which throws TypeError: Expected pattern to be a non-empty string if any value is "" or whitespace-only. Empty entries can sneak in via:

  • tsconfig.json include / exclude
  • knip plugin shorthand resolution
  • hand-written knip.json entries
  • malformed package.json main / exports fields

A single bad entry takes down all dead-code analysis instead of being skipped.

Fix

runKnip now sanitizes the parsed knip config before calling main():

  • walks top-level keys, nested plugin objects, and per-workspace overrides
  • strips empty / whitespace-only string scalars
  • filters empty / whitespace-only entries out of string arrays
  • preserves non-string entries (regexes, booleans, numbers) and intentionally-empty arrays

The bad pattern is removed; everything else still runs.

Tests

  • tests/sanitize-knip-config-patterns.test.ts — 7 unit tests covering scalars, arrays, nested plugin/workspace configs, regex preservation, and falsy non-string passthrough
  • tests/run-knip.test.ts — new case verifying the sanitizer runs after createOptions and before the first main() invocation
  • tests/regressions/scan-resilience.test.ts — issue [Bug]: Expected pattern to be a non-empty string #149 added to the registry of pipeline-resilience invariants

All 457 existing tests still pass; pnpm typecheck and pnpm lint are clean for the changed files.

Files

  • packages/react-doctor/src/utils/sanitize-knip-config-patterns.ts (new)
  • packages/react-doctor/src/utils/run-knip.ts (wires the sanitizer in)
  • packages/react-doctor/tests/sanitize-knip-config-patterns.test.ts (new)
  • packages/react-doctor/tests/run-knip.test.ts
  • packages/react-doctor/tests/regressions/scan-resilience.test.ts
  • .changeset/issue-149-empty-pattern-knip.md
Open in Web Open in Cursor 

knip funnels every entry/project/ignore pattern through picomatch,
which throws 'Expected pattern to be a non-empty string' if any
value is empty or whitespace-only. Empty patterns can sneak in via
tsconfig include, plugin shorthand resolution, or hand-written
knip.json entries — knocking out the entire dead-code step.

runKnip now walks the parsed knip config (top-level keys, nested
plugin objects, per-workspace overrides) and removes empty /
whitespace-only string patterns — both as scalars and as entries
inside arrays — before invoking knip's main().

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-doctor-website Ready Ready Preview, Comment May 4, 2026 10:11am

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.

[Bug]: Expected pattern to be a non-empty string

2 participants