Prod showed rogue conversations with titles like Please Provide Your First Message. I'll Generate A, tied to long-lived LLM work.
Root cause: the frontend WebSocket keepalive sends { "type": "ping", "email": ... } with nomessage or conversation_id. Both chat consumers treated that as a new chat:
Call title generator on empty/null text
Create a conversation
Run the full LLM pipeline
An idle tab (e.g. mobile viewport left open) heartbeats every ~25s and can spawn these repeatedly.
Frontend already guards empty prompt text in the form, but the backend did not reject empty/whitespace payloads, and heartbeats were not ignored.
Expected
type: ping frames are ignored (no conversation, no title LLM, no chat pipeline)
Empty / whitespace-only user messages are rejected before any DB or LLM work
## Problem
Prod showed rogue conversations with titles like `Please Provide Your First Message. I'll Generate A`, tied to long-lived LLM work.
Root cause: the frontend WebSocket keepalive sends `{ "type": "ping", "email": ... }` with **no** `message` or `conversation_id`. Both chat consumers treated that as a new chat:
1. Call title generator on empty/null text
2. Create a conversation
3. Run the full LLM pipeline
An idle tab (e.g. mobile viewport left open) heartbeats every ~25s and can spawn these repeatedly.
Frontend already guards empty prompt text in the form, but the backend did not reject empty/whitespace payloads, and heartbeats were not ignored.
## Expected
- `type: ping` frames are ignored (no conversation, no title LLM, no chat pipeline)
- Empty / whitespace-only user messages are rejected before any DB or LLM work
- REST prompt create path also rejects empty text
## Scope
- Backend: `consumers.py`, `consumers_graph.py`, `PromptSerializer`, `ConversationDetailView`
- Frontend defense-in-depth (trim + `sendMessage` guard) may land in `chat_web_app` separately if needed
## Acceptance
- [ ] Ping heartbeats create zero conversations
- [ ] Empty/whitespace WS payloads return an error and create nothing
- [ ] `PromptSerializer` rejects blank/whitespace messages
- [ ] Tests cover heartbeat ignore + empty-message rejection
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Prod showed rogue conversations with titles like
Please Provide Your First Message. I'll Generate A, tied to long-lived LLM work.Root cause: the frontend WebSocket keepalive sends
{ "type": "ping", "email": ... }with nomessageorconversation_id. Both chat consumers treated that as a new chat:An idle tab (e.g. mobile viewport left open) heartbeats every ~25s and can spawn these repeatedly.
Frontend already guards empty prompt text in the form, but the backend did not reject empty/whitespace payloads, and heartbeats were not ignored.
Expected
type: pingframes are ignored (no conversation, no title LLM, no chat pipeline)Scope
consumers.py,consumers_graph.py,PromptSerializer,ConversationDetailViewsendMessageguard) may land inchat_web_appseparately if neededAcceptance
PromptSerializerrejects blank/whitespace messages