Skip to content

fix(client): serialize response cache invalidation - #2688

Open
tandede wants to merge 1 commit into
modelcontextprotocol:mainfrom
tandede:fix-async-cache-invalidation-race
Open

fix(client): serialize response cache invalidation#2688
tandede wants to merge 1 commit into
modelcontextprotocol:mainfrom
tandede:fix-async-cache-invalidation-race

Conversation

@tandede

@tandede tandede commented Aug 19, 2026

Copy link
Copy Markdown

Summary

  • serialize response-cache mutations per logical key so a delayed asynchronous ResponseCacheStore.set() cannot restore stale data after invalidation
  • preserve invocation order so writes started after list_changed or resources/updated invalidation remain cached
  • add deterministic regressions for both stale-write removal and fresh-write preservation
  • add a patch changeset for @modelcontextprotocol/client

Why

ResponseCacheStore permits asynchronous implementations. The existing generation check prevents a response that was already stale before write() from being stored, but it cannot stop an invalidation that arrives while store.set() is already pending:

  1. write() passes the generation check and enters an asynchronous set().
  2. An invalidation increments the generation and finishes delete() before that set has applied anything.
  3. The delayed set then commits the old response after the invalidation.

Serializing mutations for each logical cache key makes the earlier set finish before its invalidation delete. A fresh write invoked after that invalidation queues behind the delete, so it is not removed.

Test plan

  • pnpm --filter @modelcontextprotocol/client test (806 passed)
  • pnpm typecheck:all
  • pnpm lint:all
  • pnpm build:all

@tandede
tandede requested a review from a team as a code owner August 19, 2026 14:21
@changeset-bot

changeset-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8ec0121

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/client Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/server Patch
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/codemod Patch
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Aug 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2688

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2688

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2688

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2688

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2688

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2688

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2688

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2688

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2688

commit: 8ec0121

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