Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Disconnecting during a Last-Event-ID replay leaves a dead SSE stream and the session answers 409 forever

Open Beginner friendly
#334 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@mcollina is already working on this.

Since Oct 19, 2026.

  • #351 by @mcollina — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript

Research direction

Start in the GET handler in src/routes/mcp.ts and trace when the stream is added, replayed, and cleaned up on close. Reproduce the described abort during delayed getMessagesFrom replay, then verify the socket is checked after replay and later GETs for the session no longer return 409.

Written by the indexing model from the issue text.

Description

Summary

If a legacy SSE client disconnects while its Last-Event-ID replay is still running, the stream it leaves behind is never cleaned up. From then on, every GET for that session gets 409.

Cause

In the GET handler (src/routes/mcp.ts), streams.add(reply) and await replayMessagesFromEventId(...) both run before any close handler is registered. A client that leaves during the replay is therefore never removed from localStreams. The heartbeat set up afterwards writes to the destroyed socket without throwing and keeps refreshing the session TTL, so nothing removes the dead stream.

Repro

  1. Run a real server, with getMessagesFrom delayed by 300ms to stand in for Redis XRANGE latency.
  2. Open a GET with Last-Event-ID and abort the client after 100ms.
  3. Every later GET for that session returns 409, and it still does 5s later with sessionTtlMs: 2000.

Suggested fix

Register the close and cleanup handlers immediately after streams.add(reply), before any await. Check raw.destroyed once the replay finishes.

🤖 Generated with Claude Code

Dominant language
TypeScript
Stars
58
Forks
15
Avg merge
1d 7h
Merged PRs (30d)
53

Getting set up

  • Ships a Dockerfile or Docker Compose file
  • No pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from platformatic/mcp

All issues in platformatic/mcp

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.