You're offline — showing cached data

MC-4352

[auto-review] A race condition exists between concurrent chat turns. A new `send` op
2026-06-13 08:46:45 SAST
Home Board MC-4352

[auto-review] A race condition exists between concurrent chat turns. A new `send` op

**Severity:** high **Location:** chat_runtime.py:193 **Flagged by:** gemini **Issue:** A race condition exists between concurrent chat turns. A new `send` operation can be init...
State Done Next Action Closed Owner Luci Runtime Closed Age 16d ago
MC-4352
Ticket is done; runtime is closed. · profile claude_opus_1m_medium · cwd /home/lucienne/workspace/mission-control · uptime 16d 4h · last activity 16d 2h ago

Description

MC-4352
**Severity:** high **Location:** chat_runtime.py:193 **Flagged by:** gemini **Issue:** A race condition exists between concurrent chat turns. A new `send` operation can be initiated while a `harvest_until_response` poll for a previous turn is active. The `send` function updates the database row for the runtime session (e.g., `last_turn_marker`, `harvest_offset`) without checking if a turn is already in progress (i.e., status is 'running'). The active `harvest_until_response` poll will then read this new state and start harvesting the response for the second message. This causes the client waiting for the first response to incorrectly receive the second response, breaking the request-response model. **Suggested fix:** In the `send` function, after acquiring the lock and fetching the current runtime session, check if its status is 'running'. If it is, another turn is in progress, and the function should raise an exception to reject the new message. This serializes turns for a given chat session, preventing the race condition. ```python # chat_runtime.py:196, inside send() def send(thread: dict, message: str, *, source: str = "api", enter: bool = True) -> dict: # ... target = models.chat_runtime_tmux_target(thread_id) with _send_lock(thread_id): current = models.get_runtime_session(session_key) if (current or {}).get("status") == "running": raise RuntimeError(f"Session {session_key} is busy processing a previous message.") pane_log = Path(_metadata(current).get("pane_log_path") or _pane_log_path(thread_id)) # ... rest of the function ``` --- Found by mc-auto-review on 2026-05-28 06:08 SAST. Repos reviewed: mission-control. auto-review-hash: dc325ca7828a

Activity

done
Luci is working...
Live
No activity yet
Help