Skip to content

fix: move handledFiles from module scope to Walker instance#16

Merged
filipenevola merged 1 commit intomainfrom
fix/walker-cache-race-condition
Mar 27, 2026
Merged

fix: move handledFiles from module scope to Walker instance#16
filipenevola merged 1 commit intomainfrom
fix/walker-cache-race-condition

Conversation

@filipenevola
Copy link
Copy Markdown
Contributor

@filipenevola filipenevola commented Mar 27, 2026

Summary

  • The module-level handledFiles Set in walker.js persisted across Walker instances within a single ESLint run. When the file cache (.eslint-meteor-files) expired mid-run (default 5s TTL), re-walking the app tree produced an empty cachedParsedFile because handledFiles caused handleFile() to skip every previously-seen file. All files linted after this point had their warnings silently dropped, making the count non-deterministic.
  • Moved handledFiles from module scope into the Walker class instance, and threaded it through handleFile/handleFolder as a parameter. Each walk now builds a complete file list independently.
  • Bumped version to 1.5.3.

Reproduction

Run eslint --no-cache . --format json on a Meteor project with no-sync-mongo-methods-on-server enabled, multiple times in quick succession. The warning count will vary between runs (e.g. 510, 538, 578) because the 5-second cache expires partway through the ~10s ESLint run.

Test plan

  • Run ESLint count 3+ times consecutively and verify the count is identical every time
  • Existing tests pass (npm test)

Made with Cursor

Two related bugs caused non-deterministic warning counts:

1. The module-level `handledFiles` Set persisted across Walker
   instances. When the file cache (`.eslint-meteor-files`) expired
   mid-run (default 5s TTL), re-walking the app tree skipped every
   file already in `handledFiles`, producing an empty
   `cachedParsedFile` written to disk.

2. `shouldSkip()` created a new Walker on every call and depended
   solely on the disk cache. If the cache expired between the
   `Program` handler writing it and `MemberExpression` reading it,
   `shouldSkip()` saw an empty file list and skipped the file.

Fixes:
- Move `handledFiles` from module scope into the Walker instance.
- Add an in-memory cache (`inMemoryCache` Map) that survives the
  entire ESLint process so `shouldSkip()` always sees the complete
  file list regardless of disk cache TTL.

Made-with: Cursor
@filipenevola filipenevola force-pushed the fix/walker-cache-race-condition branch from 684f35d to c58d0fe Compare March 27, 2026 15:39
@filipenevola filipenevola merged commit 14763d0 into main Mar 27, 2026
2 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.

1 participant