Skip to content

fix: prevent memory leak in KiloSessionPromptQueue.cancel for sessions without active tails - #10109

Merged
marius-kilocode merged 4 commits into
Kilo-Org:mainfrom
IamCoder18:fix/session-prompt-queue-memory-leak
Jun 9, 2026
Merged

fix: prevent memory leak in KiloSessionPromptQueue.cancel for sessions without active tails#10109
marius-kilocode merged 4 commits into
Kilo-Org:mainfrom
IamCoder18:fix/session-prompt-queue-memory-leak

Conversation

@IamCoder18

Copy link
Copy Markdown
Contributor

Context

Fix a memory leak in KiloSessionPromptQueue.cancel() where calling cancel on a session with no queued prompts would leave permanent entries in the module-level versions, targets, latest, and activeSince maps. This occurred because cancel() always incremented and stored a version, but cleanup only happens in enqueue's release phase.

Closes #9211

Implementation

Modified cancel() to check if the session has an active tail before modifying state. If tails.has(sessionID) is false, the function now cleans up any existing entries in versions, targets, latest, and activeSince maps instead of creating new ones.

export function cancel(sessionID: SessionID) {
  return Effect.sync(() => {
    if (!tails.has(sessionID)) {
      versions.delete(sessionID)
      targets.delete(sessionID)
      latest.delete(sessionID)
      activeSince.delete(sessionID)
      return
    }
    versions.set(sessionID, version(sessionID) + 1)
  })
}

Get in Touch

Discord: @IamCoder18

…ssions without active tails

The cancel() function was always incrementing and storing a version in the
versions map, even for sessions with no queued prompts. Since cleanup only
happens in enqueue's release phase, sessions without active tails left
permanent map entries.

Now cancel() checks if the session has an active tail before modifying state.
If no tail exists, it cleans up any existing versions/targets/latest/activeSince
entries instead of creating new ones.
@IamCoder18 IamCoder18 changed the title fix(cli): prevent memory leak in KiloSessionPromptQueue.cancel for se… fix: prevent memory leak in KiloSessionPromptQueue.cancel for sessions without active tails May 10, 2026
@kilo-code-bot

kilo-code-bot Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Resolved Issues

Previously flagged (round 1): Missing test for the memory-leak scenario — resolved: dedicated test added in test/kilocode/session-prompt-queue.test.ts (line 494).

Previously flagged (round 2): _hasInternalState exported from production namespace without an internal annotation — resolved: /** @internal - test-only helper */ JSDoc comment added above the function.

Logic Review

All three aspects of the fix are correct:

  • cancel() logic: When !tails.has(sessionID), all four stale map entries are deleted and the function returns early. When a tail is active, the version is incremented so in-flight slots detect cancellation via slot.version !== version(sessionID).
  • _hasInternalState helper: Checks the correct 4 maps (versions, targets, latest, activeSince), intentionally omitting tails since an active tail entry is valid live state. Annotated as @internal.
  • New test: Verifies that cancel() on a never-enqueued session leaves no state and that a subsequent enqueue() executes the work branch normally.
  • Changeset: .changeset/session-prompt-queue-memory-leak.md added with correct patch bump for @kilocode/cli and accurate user-facing description.
Files Reviewed (3 files)
  • packages/opencode/src/kilocode/session/prompt-queue.ts
  • packages/opencode/test/kilocode/session-prompt-queue.test.ts
  • .changeset/session-prompt-queue-memory-leak.md

Reviewed by claude-sonnet-4.6 · 172,820 tokens

@johnnyeric

Copy link
Copy Markdown
Contributor

Hey @IamCoder18, could you provide details about how the issue was reproduced and fix tested? Also, please consider adding a unit test to prevent the issue from happening again.

Adds a test that verifies cancel() on a session with no active tail
does not leave stale entries in the internal maps (versions, targets,
latest, activeSince). Also adds _hasInternalState() debug helper to
verify map cleanup.
Comment thread packages/opencode/src/kilocode/session/prompt-queue.ts
@IamCoder18

Copy link
Copy Markdown
Contributor Author

Hey @johnnyeric, added the test as requested.

The test verifies that calling cancel() on a session with no active tail doesn't leave stale entries in the internal maps (versions, targets, latest, activeSince). I added a debug helper _hasInternalState() to check map state.

The test:

  1. Creates a fresh session ID (no prior enqueue)
  2. Calls cancel() on it
  3. Verifies no internal state remains (_hasInternalState() === false)
  4. Verifies subsequent enqueue() works normally

Without the fix, step 3 fails (I've ran it and test this) because cancel() leaves a stale entry in the versions map.

@johnnyeric
johnnyeric requested a review from imanolmzd-svg May 13, 2026 11:47
slamj1 pushed a commit to slamj1/kilocode that referenced this pull request May 16, 2026
jliounis pushed a commit to jliounis/kilocode that referenced this pull request May 18, 2026
@marius-kilocode
marius-kilocode merged commit dbddefd into Kilo-Org:main Jun 9, 2026
11 checks passed
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
…queue-memory-leak

fix: prevent memory leak in KiloSessionPromptQueue.cancel for sessions without active tails
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.

[autodetected memoryleak] Avoid prompt queue cancel version retention

3 participants