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

tasks/result leaves a waiter behind forever when its client has already disconnected

Open Beginner friendly
#333 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.

  • #354 by @mcollina — open

Assessment

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

Research direction

Start in TaskWaiters.wait in src/stores/task-store.ts, then check how handleTasksResult in src/handlers.ts handles an already-aborted signal. Add or run the unit-level case described in the issue: wait() with an already-aborted signal should leave the waiter count at zero. Done means no waiter is registered for that signal.

Written by the indexing model from the issue text.

Description

Summary

A tasks/result request whose client has already disconnected leaves an entry in TaskWaiters that is never removed.

Cause

  1. handleTasksResult (src/handlers.ts) aborts its controller before waiting when res.destroyed || res.socket?.destroyed.
  2. TaskWaiters.wait (src/stores/task-store.ts) then registers the waiter anyway and adds an abort listener to that already-aborted signal. The listener never fires.
  3. Only a local notify() removes the entry. That never happens for a task running on another instance, or for a task that expires: the final updateStatus returns null, so nothing is notified.

Repro

With the Redis backend, send 200 tasks/result requests for a long-running task and destroy each socket right after sending. 200 waiters remain, and they are still there after the task's ttl has passed.

At the unit level: wait() called with an already-aborted signal leaves size === 1.

A caller who owns one long-running task can use this to grow the server's memory.

Suggested fix

In TaskWaiters.wait, reject immediately and register nothing when signal?.aborted is already true. Alternatively, skip waiting in handleTasksResult when the signal has already aborted.

🤖 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.