Skip to content

fix(lint): resolve snippet typechecking failures on Windows due to mi…#147

Merged
KayleeWilliams merged 4 commits into
inthhq:mainfrom
Adityakk9031:#145
Jul 15, 2026
Merged

fix(lint): resolve snippet typechecking failures on Windows due to mi…#147
KayleeWilliams merged 4 commits into
inthhq:mainfrom
Adityakk9031:#145

Conversation

@Adityakk9031

@Adityakk9031 Adityakk9031 commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

closes:#145

Description

On Windows, the snippet:types lint checks were silently passing even when snippets contained syntax or compilation errors. This was caused by a path separator mismatch between the virtual file cache key storage and the TypeScript compiler host lookups.

This PR resolves the issue by normalizing all paths to POSIX-style (forward slashes /) when storing and querying the virtual files in the compiler host callbacks.

Root Cause

  1. In snippet-typecheck.ts, virtualDir was resolved using projectRoot (using Windows backslashes \), and the file name was joined using /. This stored paths like C:\path\to\project/.leadtype-snippet-0/main.ts in the virtualFiles Map.
  2. The TypeScript compiler internally normalizes paths to use forward slashes (e.g. C:/path/to/project/.leadtype-snippet-0/main.ts).
  3. Compiler host callbacks (like host.fileExists, host.getSourceFile) queried files using the forward-slashed version, causing virtualFiles.get(fileName) to return undefined and skip typechecking.

Changes

  • Imported normalizeDocsPath from ../internal/docs-url.
  • Wrapped lookup keys and parameters in host callbacks (host.fileExists, host.readFile, host.directoryExists, host.getSourceFile, and the diagnostics loop) with normalizeDocsPath().
  • Formatted code in snippet-typecheck.ts with Biome/Ultracite.

Verification

Ran the vitest suite for snippet typechecking on Windows:

bun test snippet-typecheck.test.ts

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@KayleeWilliams, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 59 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c3730283-330c-4880-9490-595a0aeb2c0f

📥 Commits

Reviewing files that changed from the base of the PR and between 4d861f5 and 1c15bd0.

📒 Files selected for processing (1)
  • .changeset/calm-paths-agree.md
📝 Walkthrough

Walkthrough

The snippet typechecker normalizes Windows-style paths for virtual file storage, compiler-host lookups, source retrieval, and diagnostic mapping. Tests cover the exported helper and Windows path-separator regression behavior.

Changes

Virtual path normalization

Layer / File(s) Summary
Compiler-host path resolution and diagnostics
packages/leadtype/src/lint/snippet-typecheck.ts, packages/leadtype/src/lint/snippet-typecheck.test.ts
toPosixPath normalizes path separators across virtual file handling, compiler-host lookups, diagnostic mapping, and regression tests.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • Issue 145 — Addresses the Windows path-separator mismatch in snippet typechecking.

Poem

A bunny hops through paths unseen,
Turning backslashes bright and clean.
Files resolve and errors align,
Snippets typecheck right on time.
“No tangled paths today!”
Carrots cheer the fix away.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: fixing Windows snippet typechecking failures caused by path separator mismatches.
Description check ✅ Passed The description accurately explains the Windows path-separator bug and the normalization fix in this changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ No critical issues — the fix is correct and mergeable; one coverage gap and one naming nit worth a look.

Reviewed changes — normalizes virtual-file paths to POSIX separators so snippet:types typechecking actually runs on Windows instead of silently passing.

  • Normalize compiler-host path keysvirtualFiles store/lookup and the host.fileExists / host.readFile / host.directoryExists / host.getSourceFile / diagnostics-loop lookups are now wrapped in normalizeDocsPath, so the backslash-containing keys produced by resolve(projectRoot) on Windows match the forward-slashed paths TypeScript's compiler host queries with.

The fix is sound: virtualDirs is derived from the now-normalized virtualFiles keys so it stays consistent, createProgram root names come from those keys, and on POSIX normalizeDocsPath is an identity transform so there's no behavior change. I found no store/lookup site that was missed.

ℹ️ No regression test exercises the Windows path-separator scenario

The bug only reproduces when resolve(projectRoot) yields backslashes, i.e. on Windows. The existing suite builds projects with mkdtemp, which returns OS-native (forward-slashed) paths on CI, so the mismatch never occurs there and a future regression on this code path would pass unnoticed.

Technical details
# No regression test for the Windows path-separator fix

## Affected sites
- `packages/leadtype/src/lint/snippet-typecheck.test.ts` — all cases use `mkdtemp`; none force a backslash-containing `projectRoot`.
- `packages/leadtype/src/lint/snippet-typecheck.ts:231``virtualDir` interpolates `resolve(projectRoot)`; the separator mix is the whole bug.

## Required outcome
- A test that fails on the pre-fix code and passes on the post-fix code, without depending on the host OS being Windows.

## Suggested approach (optional)
- Directly unit-test the normalization contract: assert `typecheckSnippets` still reports a snippet error when virtual keys would be stored backslashed — e.g. by exercising `normalizeDocsPath` round-tripping, or by refactoring the `virtualDir` construction to accept an injectable path-join so a `\\`-style root can be simulated on POSIX.
- If neither is worth the churn, a one-line comment near line 231 noting *why* normalization is required would at least protect the invariant from a well-meaning future simplification.

## Open questions for the human
- Is a POSIX-runnable regression test worth the refactor here, or is documenting the invariant sufficient given Windows isn't in CI?

ℹ️ Nitpicks

  • normalizeDocsPath (from ../internal/docs-url) is a docs-URL helper that happens to be a generic \\/ replace. Reusing it for compiler-host paths is functionally correct but semantically off; a neutrally-named toPosixPath/normalizeSeparators helper would read truer to intent. Not blocking.

Pullfrog  | Fix it ➔View workflow run | Using Claude Opus𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ No new issues in the fix itself — the refactor is correct and mergeable. One minor suggestion inline about the added test.

Reviewed changes — the delta since the prior pullfrog review (59986ae): a refactor from the reused normalizeDocsPath helper to a purpose-named local one, plus a unit test.

  • Introduced local toPosixPath helpersnippet-typecheck.ts now defines and exports toPosixPath (filePath.replace(/\\/g, "/")) and uses it at every virtualFiles/virtualDirs store and lookup site, replacing the normalizeDocsPath import. This cleanly resolves the prior naming nit — the compiler-host path normalization no longer borrows a docs-URL helper.
  • Added a toPosixPath unit testsnippet-typecheck.test.ts asserts backslash paths convert to forward slashes.

The refactor is behavior-preserving: toPosixPath is an equivalent generic \\/ replace, all store/lookup keys stay consistent, and on POSIX it remains an identity transform.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread packages/leadtype/src/lint/snippet-typecheck.test.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes — the delta since the prior pullfrog review (e1062ea): a POSIX-runnable regression test that closes the last open coverage gap.

  • Added Windows path-separator integration regression testsnippet-typecheck.test.ts now drives typecheckSnippets end-to-end through lintWithTypecheck with a backslash-containing projectRoot (${projectRoot}${path.sep}subdir\subsubdir) and asserts a snippet:types error is reported. On POSIX the injected backslash makes the stored virtual-file keys mismatch TypeScript's forward-slashed host queries pre-fix (the diagnostic is treated as a real-project file and skipped, so the test fails), while post-fix toPosixPath normalizes both store and lookup so the error surfaces. This is precisely the "fails on pre-fix, passes on post-fix without requiring Windows" outcome the prior review requested.

The test is self-contained: the snippet (const x: number = "this is a string";) has no imports, so the fabricated non-existent projectRoot doesn't perturb tsconfig or module resolution — the assignment is a type error regardless of config. Prior naming and coverage concerns are both now resolved; the fix is mergeable.

Pullfrog  | View workflow run | Using Claude Opus𝕏

@KayleeWilliams KayleeWilliams merged commit 68f12d0 into inthhq:main Jul 15, 2026
3 checks passed
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.

2 participants