Skip to content

send_message_streaming_* path bypasses agent_msg_locks — concurrent stream + non-stream loses messages #3737

Description

@houko

Location

  • crates/librefang-kernel/src/kernel/mod.rs:5115-5499 (send_message_streaming_* family)
  • crates/librefang-kernel/src/kernel/mod.rs:5985 (run_agent_loop_streaming)
  • crates/librefang-kernel/src/kernel/mod.rs:5431 (only try_read on config_reload_lock, no agent/session mutex)

Problem
Non-streaming send_message_full acquires agent_msg_locks[agent_id] for the duration of the LLM loop (mod.rs:4733). The streaming path only does try_read on config_reload_lock and spawns the loop without taking either agent_msg_locks or session_msg_locks. Concurrent streaming-from-dashboard + non-streaming-from-channel-bridge both load the same session row, mutate session.messages independently, then race to save_session — last write wins.

Impact
A user typing into dashboard while a channel adapter relays a message: one branch's user message + assistant reply silently disappears from persisted history. Worse: each branch's LLM also sees a different (stale) context, so replies are computed from an inconsistent view.

Fix
Take agent_msg_locks[agent_id].lock_owned().await (or .try_lock_owned() if streaming wants to fail-fast on contention) before spawning the streamed loop, move the OwnedMutexGuard into the spawned task. Drop the misleading "non-blocking try_read on config_reload_lock" comment — the lock that was needed is agent_msg_locks, not config-reload.


Filed via automated multi-perspective audit (security / concurrency / architecture / error-handling / frontend / performance subagents). Curated against #3359#3409 to avoid duplicates.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/kernelCore kernel (scheduling, RBAC, workflows)bugSomething isn't workinghas-prA pull request has been linked to this issueneeds-triageAuto-applied when the issue title/body matched no area label — needs maintainer reviewseverity/highSignificant functional, security, or performance impact

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions