Skip to content

fix(client): scope corrupt-cache-entry deletion to the probed partition#2485

Open
felixweinberger wants to merge 1 commit into
mainfrom
fix/partition-scoped-corrupt-delete
Open

fix(client): scope corrupt-cache-entry deletion to the probed partition#2485
felixweinberger wants to merge 1 commit into
mainfrom
fix/partition-scoped-corrupt-delete

Conversation

@felixweinberger

@felixweinberger felixweinberger commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #2468 review discussion: read()'s corrupt-document cleanup deleted both partitions, but corruption is evidence about the one physical entry _probe returned — on a shared multi-principal store (the per-user cachePartition deployment the caching guide documents), one principal's corrupt private entry also evicted the healthy shared entry for every co-tenant.

_probe now reports which partition it hit and the cleanup deletes exactly that entry. Store delete failures during cleanup are reported through the error sink instead of rejecting the read, per the class contract.

How Has This Been Tested?

Unit tests pin the single-partition delete (with a non-empty cachePartition so a two-partition regression is observable — mutation-checked), the failing-delete-is-reported path, and the existing corrupt-document suite; the full client suite passes cold. Driven end-to-end through the built dist via the public responseCacheStore option: corrupt entry → one report, one delete targeting the probed partition, clean wire refetch.

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

read()'s decode-failure cleanup deleted both partitions, but corruption
is evidence about the one physical entry _probe returned — on a shared
multi-principal store the unconditional two-partition delete evicted
healthy co-tenant entries. _probe now reports which partition it hit and
the cleanup deletes exactly that entry, with store delete failures
routed to the error sink per the class contract.
@felixweinberger felixweinberger requested a review from a team as a code owner July 13, 2026 17:24
@changeset-bot

changeset-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 80a94c5

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

This PR includes changesets to release 5 packages
Name Type
@modelcontextprotocol/client Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/server Patch
@modelcontextprotocol/server-legacy 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 Jul 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

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

@modelcontextprotocol/core

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

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

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

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: 80a94c5

@felixweinberger felixweinberger changed the title chore: version the codemod with the core SDK fixed group fix(client): scope corrupt-cache-entry deletion to the probed partition Jul 13, 2026
Comment on lines +1 to +5
---
'@modelcontextprotocol/client': patch
---

A corrupt cached document now deletes only the partition it was read from. The previous cleanup deleted both partitions, so on a shared multi-principal store one principal's corrupt private entry also evicted the healthy shared entry. Store delete failures during this cleanup are reported through the error sink instead of rejecting the read.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 The PR title and description describe a completely different change — adding @modelcontextprotocol/codemod to the changesets fixed group — but the diff contains none of that: it is a client responseCache fix (partition-scoped corrupt-entry deletion) with a client-only changeset, and .changeset/config.json is untouched. If merged as-is, the claimed codemod-versioning fix silently does not ship (the npm install @modelcontextprotocol/codemod@2.0.0-beta.4 failure the description promises to fix remains), and the merge record misdescribes the change — either push the intended diff or replace the title/description with ones describing the actual responseCache fix. Separately (minor), the changeset's last sentence ('reported through the error sink instead of rejecting the read') implies delete failures used to reject the read; they never did — the old _deleteBoth already caught and reported them — so reword it to say the existing error-sink reporting is preserved.

Extended reasoning...

The PR metadata describes a change that is not in the diff

Title/description vs. actual content. The title is chore: version the codemod with the core SDK fixed group, and the description explains adding @modelcontextprotocol/codemod to the changesets fixed group (plus a codemod changeset) so the pending beta.4 release includes it. The diff, however, contains exactly three files: .changeset/partition-scoped-corrupt-delete.md (patching only @modelcontextprotocol/client), packages/client/src/client/responseCache.ts, and packages/client/test/client/responseCacheCodec.test.ts. There is no change to .changeset/config.json, no codemod changeset, and no mention of the codemod package anywhere in the diff.

Corroborating evidence. The changeset-bot comment on this PR confirms the release contents: 5 packages bumped (client, core, server, server-legacy, core-internal) — @modelcontextprotocol/codemod is absent. The bot's link also shows the branch name is fix/partition-scoped-corrupt-delete, which matches the diff's content, not the title. And at HEAD, .changeset/config.json's fixed group still lists only core/client/server/server-legacy — so the described change is not present anywhere; it simply does not ship. The most likely explanation is the title/description were copy-pasted from a different PR (the branch and code are internally consistent as the responseCache fix).

Step-by-step consequence if merged as-is:

  1. The merge commit records "chore: version the codemod with the core SDK fixed group" — a change that never happened. Anyone auditing history or generating release notes from PR titles records a phantom change.
  2. The author (and reviewers) believe the codemod-versioning problem is fixed. It is not: the fixed group is unchanged.
  3. The next release round runs: changesets bumps the fixed group to 2.0.0-beta.4, the codemod stays at 2.0.0-beta.3 (no changeset, not in the fixed group).
  4. A user follows the migration guide's "all v2 packages share one version" guarantee and runs npm install @modelcontextprotocol/codemod@2.0.0-beta.4no matching version — exactly the failure the description claims to fix.

Why this is normal severity rather than a description nit. The in-diff code is correct and well-tested, and its changeset accurately describes it — the defect is purely at the PR-metadata level. But this is not a stale or imprecise description of the code in the diff; it is a wholesale mismatch where an intended fix silently fails to ship while the record says it shipped. The author needs to act before merge: either the wrong branch/diff was pushed (push the intended .changeset/config.json change), or the metadata was pasted from another PR (retitle/re-describe this one as the responseCache partition-scoped corrupt-delete fix and file the codemod change separately).

Secondary (nit): one changeset sentence implies a behavior change that isn't one

.changeset/partition-scoped-corrupt-delete.md ends with: "Store delete failures during this cleanup are reported through the error sink instead of rejecting the read." In a changelog, "instead of" reads as a before/after contrast — implying the pre-fix path rejected read() on a store delete failure. It did not: the old corrupt path called this._deleteBoth(method, params ?? ''), and _deleteBoth (still present at packages/client/src/client/responseCache.ts:431) wraps each partition's delete in try/catch, routes failures to this._reportError, and always resolves. Verified against the pre-fix code (git show 80a94c5~1): a delete failure never rejected the read before this PR. Error-sink reporting is preserved pre-existing behavior, not part of this change. Suggested reword: "Store delete failures during this cleanup continue to be reported through the error sink." Nothing breaks if this merges as-is, but changelog readers would otherwise infer a rejection bug existed.

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