Skip to content

WIP: Bust pin cache when solargraph's own lib code changes - #54

Draft
apiology wants to merge 1 commit into
masterfrom
fix-pin-cache-stale-version-key
Draft

WIP: Bust pin cache when solargraph's own lib code changes#54
apiology wants to merge 1 commit into
masterfrom
fix-pin-cache-stale-version-key

Conversation

@apiology

@apiology apiology commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • PinCache.work_dir keys the on-disk cache directory only on Solargraph::VERSION, a hardcoded string. Marshal.load silently tolerates deserializing pins that were serialized by an older Pin::Callable definition with fewer ivars (missing ones just read back as nil), so a gem source swap that changes Pin behavior without bumping VERSION can leave stale, schema-mismatched pins cached on disk after upgrading.
  • Flagged via Fix @generic return type lost when method also declares a block param castwide/solargraph#1274 (comment): a consumer bisected a reported regression by swapping their solargraph gem revision (git-sourced, same VERSION before/after) without clearing ~/.cache/solargraph. That gave Pin::Callable#block_required? == false (nil read back from the old-schema cached pin) for an RBS signature whose block is genuinely required, letting a generic-returning block overload spuriously match a call site with no block and leak an unresolved generic<X> into the inferred return type.
  • I reproduced this precisely: populate the pin cache on the pre-Fix @generic return type lost when method also declares a block param castwide/solargraph#1274 commit, switch to the post-Fix @generic return type lost when method also declares a block param castwide/solargraph#1274 commit under the same forced VERSION, don't clear the cache -> same symptom on the same minimal repro from the linked comment. Clearing the cache (or this fix) makes it go away.
  • Fix: fold a digest of solargraph's own lib/ file mtimes+sizes into work_dir, so any code change -- not just a VERSION bump -- busts the cache automatically.

Marked draft/WIP: this is a real, reproduced bug, but low urgency (self-resolves once affected users clear their cache once) -- opening now mainly so the finding and fix aren't lost.

Test plan

  • bundle exec rspec spec/pin_cache_spec.rb -- new spec covers digest sensitivity and that it's folded into work_dir
  • bundle exec rspec -- full suite green (1625 examples, 0 failures, 60 pending)
  • bundle exec rubocop lib/solargraph/pin_cache.rb spec/pin_cache_spec.rb -- clean
  • bundle exec solargraph typecheck --level strong lib/solargraph/pin_cache.rb -- no new problems on modified lines
  • Manually reproduced the stale-cache regression from the linked comment and confirmed this fix resolves it

Generated with Claude Code

https://claude.ai/code/session_01QYGSCei2o8gmaghfjc15Uo

…VERSION

PinCache.work_dir keys the on-disk cache directory on Solargraph::VERSION
alone. Marshal silently tolerates loading pins serialized by an older
Pin::Callable definition with fewer ivars (missing ones just read back as
nil), so a gem source swap that changes Pin behavior without bumping
VERSION -- e.g. a downstream Gemfile switching a git-sourced solargraph
dependency to a different commit, common in fork-based development --
can leave stale pins in place after upgrading.

This was flagged via castwide#1274 (comment):
after PR castwide#1274 added Pin::Callable#block_required?, a consumer bisecting
by swapping gem revisions without clearing ~/.cache/solargraph got
block_required? == false (nil from the old-schema cached pin) for an
RBS signature whose block is genuinely required, letting a
generic-returning block overload spuriously match a call with no block
and leak an unresolved generic<X> into the inferred return type.
Reproduced by populating the cache on the pre-castwide#1274 commit and then
switching to the post-castwide#1274 commit under the same forced VERSION,
without clearing the cache.

Fold a digest of solargraph's own lib/ file mtimes+sizes into work_dir
so any code change -- not just a VERSION bump -- busts the cache.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QYGSCei2o8gmaghfjc15Uo
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