Skip to content

fix(examples): resume streams whose IDs contain underscores - #2567

Open
patrickswedish wants to merge 2 commits into
modelcontextprotocol:mainfrom
patrickswedish:fix/in-memory-event-store-resume
Open

fix(examples): resume streams whose IDs contain underscores#2567
patrickswedish wants to merge 2 commits into
modelcontextprotocol:mainfrom
patrickswedish:fix/in-memory-event-store-resume

Conversation

@patrickswedish

@patrickswedish patrickswedish commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Fixes #2560.

  • Resolve an event's stream ID from the metadata already stored for that event instead of parsing an underscore-delimited ID.
  • Replay stored events in Map insertion order, which is their actual chronology.
  • Add a regression test for the standalone _GET_stream that verifies the returned stream ID and replay order.

Why

Splitting an event ID on the first underscore returns an empty stream ID for _GET_stream. That prevents Last-Event-ID resume from reconnecting the standalone stream correctly. Parsing is also inherently ambiguous for any stream ID containing underscores.

Validation

  • pnpm --filter @mcp-examples/shared run check
  • pnpm --filter @mcp-examples/shared run test — 2 test files, 3 tests passed

No changeset is included because @mcp-examples/shared is a private examples workspace package.

@patrickswedish
patrickswedish requested a review from a team as a code owner July 27, 2026 22:47
@changeset-bot

changeset-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 377856d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-new Bot commented Jul 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

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

@modelcontextprotocol/core

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

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

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

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: 377856d

@patrickswedish
patrickswedish force-pushed the fix/in-memory-event-store-resume branch from b7894fe to 657390d Compare July 27, 2026 23:27
@patrickswedish patrickswedish changed the title fix(examples): fix stream ID resolution and event ordering in InMemoryEventStore fix(examples): resume streams whose IDs contain underscores Jul 27, 2026

@knoal knoal 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.

Reviewing via MCE A/B pilot 9 (sophia@hermes.local).

Summary

Fixes stream ID extraction for event IDs containing underscores. The original code eventId.split('_')[0] was incorrect for event IDs like stream_with_underscore_event123 — it would extract stream instead of the full stream ID. The fix uses the events Map to look up the actual stream ID. 45/-6 LOC, 2 files.

What's good

  • Real bug fix — the split-and-take-first approach is brittle; the Map lookup is the correct approach.
  • Also fixes the ordering — replaces explicit sort with Map iteration order (insertion order is the event chronology). O(n) vs O(n log n).
  • The test that exposed the bug is in the diff — likely a failing test that was added in the same PR.

APPROVE — clean bug fix.

— sophia

Resolve stream IDs from stored event metadata and replay events in insertion order so standalone GET streams resume correctly.

Signed-off-by: Patrick Ribbsaeter <patrickswedish@gmail.com>
@patrickswedish
patrickswedish force-pushed the fix/in-memory-event-store-resume branch from 657390d to e7e2c38 Compare July 28, 2026 17:07
@patrickswedish

Copy link
Copy Markdown
Author

CI note: the Node 20 job failed only because the Cloudflare compatibility worker did not become ready within 60 seconds (last probe: ECONNREFUSED; no worker stderr/stdout). The job completed 370 tests successfully before that timeout, and the Node 22 and Node 24 matrix jobs passed. The full main workflow also passed on the preceding PR revision. I do not have permission to rerun upstream Actions; could a maintainer please rerun the failed Node 20 job?

@knoal knoal 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.

Re-checking — the test (20) workflow is FAILING. This is a Node 20-specific test failure (the equivalent test (22) and test (24) both pass). The other 18 tests pass.

Recommend:

  1. Check the test (20) logs for the specific failure
  2. Node 20 is the LTS version that's still widely used; the fix likely needs to handle a Node 20-specific behavior
  3. May be related to a Node 20 + Vitest 3.x compatibility issue (vitest 3 dropped Node 18 but Node 20 should work)

HOLD until CI is green on all Node versions.

— sophia

Signed-off-by: Patrick Ribbsaeter <hello@glasheldereindhoven.nl>
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.

InMemoryEventStore: standalone-stream resume broken by getStreamIdFromEventId split

2 participants