Skip to content

fix(chat-context): clean up session entries on disconnect - #2959

Open
axelray-dev wants to merge 7 commits into
Chainlit:mainfrom
axelray-dev:fix/2951-chat-context-memory-leak
Open

axelray-dev wants to merge 7 commits into
Chainlit:mainfrom
axelray-dev:fix/2951-chat-context-memory-leak

Conversation

@axelray-dev

@axelray-dev axelray-dev commented Jun 12, 2026

Copy link
Copy Markdown

Fixes #2951

Problem

The global chat_contexts dict in backend/chainlit/chat_context.py accumulates a message list per session_id but never removes entries when sessions disconnect. Over time this causes unbounded memory growth and eventual OOM.

Root Cause

The disconnect handler in socket.py cleans up user_sessions and calls session.delete(), but does not remove the session's entry from chat_contexts.

Fix

  1. Added ChatContext.delete_session(session_id) to remove a session's entry from chat_contexts.
  2. Called it from the clear() function inside the disconnect handler, alongside the existing user_sessions cleanup.

Tests

3 new tests in backend/tests/test_chat_context.py:

  • test_delete_session_removes_entry: verifies entry is removed after adding a message
  • test_delete_session_nonexistent: verifies no error for unknown session ID
  • test_delete_session_without_session: verifies deletion works without an active Chainlit context

All 31 tests pass: PYTHONPATH=. python -m pytest tests/test_chat_context.py -v


Summary by cubic

Fixes #2951 by removing session entries from chat_contexts on disconnect to prevent unbounded memory growth. Previously entries persisted after disconnect; now socket.clear() deletes them, and cleanup runs even when session persistence fails.

  • Bug Fixes
    • Added ChatContext.delete_session(session_id) and call it in socket.clear() after user_sessions cleanup.
    • Moved cleanup into a finally block so it always runs, even if on_chat_end or persist_user_session raises.
    • Added tests for deletion, unknown IDs, deletion without an active context, and cleanup when persistence fails.

Written for commit 595f48e. Summary will update on new commits.

Review in cubic

Co-Authored-By: Codex <codex@openai.com>
@axelray-dev
axelray-dev marked this pull request as ready for review June 13, 2026 14:24
@dosubot dosubot Bot added size:XS This PR changes 0-9 lines, ignoring generated files. backend Pertains to the Python backend. bug Something isn't working unit-tests Has unit tests. labels Jun 13, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 3 files

Re-trigger cubic

@dokterbob

Copy link
Copy Markdown
Collaborator

@codex review

@dokterbob

Copy link
Copy Markdown
Collaborator

@axelray-dev This looks good to me but I would love it if at least one other user/dev could validate that this doesn't have unintended side-effects. Unfortunately, I lack the time to do this investigation myself.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes chat-context memory growth by removing session entries after WebSocket disconnect cleanup.

Changes:

  • Adds explicit chat-context session deletion.
  • Integrates deletion into disconnect cleanup.
  • Adds unit tests for deletion behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
backend/chainlit/chat_context.py Adds session-entry deletion.
backend/chainlit/socket.py Deletes chat context during disconnect cleanup.
backend/tests/test_chat_context.py Tests deletion scenarios.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

if session.id in user_sessions:
user_sessions.pop(session.id)
# Clean up the chat context
chat_context.delete_session(session.id)

@dokterbob dokterbob left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please address the copilot feedback thoroughly; e.g. ensure cleanup even when there's errors during the chat, preferably demonstrated in failing unit tests.

@axelray-dev

Copy link
Copy Markdown
Author

Thanks for the feedback. I moved both the chat-end callback and session persistence inside a try/finally block, so the existing immediate cleanup or timeout cleanup is still scheduled when either operation raises. I also added a regression test that makes persist_user_session() fail and verifies that user-session state, chat context, and the WebSocket session are still cleaned up. Targeted backend tests pass (67 passed) and Ruff is clean. I left the review thread unresolved for verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Pertains to the Python backend. bug Something isn't working size:XS This PR changes 0-9 lines, ignoring generated files. unit-tests Has unit tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory leak in chat_context

3 participants