Skip to content

fix(mcp): drain elicitation_rx concurrently in run_inline_tool_loop#2548

Merged
bug-ops merged 2 commits intomainfrom
2542-elicitation-deadlock
Mar 31, 2026
Merged

fix(mcp): drain elicitation_rx concurrently in run_inline_tool_loop#2548
bug-ops merged 2 commits intomainfrom
2542-elicitation-deadlock

Conversation

@bug-ops
Copy link
Copy Markdown
Owner

@bug-ops bug-ops commented Mar 31, 2026

Summary

  • Fixes elicitation deadlock in run_inline_tool_loop (phase 3 of feat(mcp): elicitation during tool execution — phase 2 #2522)
  • run_inline_tool_loop now takes &mut self and wraps each execute_tool_call_erased in tokio::select! that concurrently drains elicitation_rx
  • handle_elicitation_event visibility changed to pub(super) for cross-module access from mod.rs

Root cause

run_inline_tool_loop called execute_tool_call_erased sequentially with no concurrent drain of elicitation_rx. When an MCP tool sent an elicitation event and blocked waiting for a response, execute_tool_call_erased also blocked waiting for the tool — classic deadlock.

Test plan

  • cargo +nightly fmt --check passes
  • cargo clippy --workspace -- -D warnings passes
  • cargo nextest run --workspace --lib --bins — 7055/7055 passed
  • New regression test elicitation_event_during_tool_execution_is_handled with a blocking executor that simulates the real MCP scenario; times out in 5s if deadlock recurs
  • Existing inline_tool_loop_tests updated (6 call sites: let agentlet mut agent)

Closes #2542

@github-actions github-actions bot added documentation Improvements or additions to documentation rust Rust code changes core zeph-core crate bug Something isn't working size/M Medium PR (51-200 lines) labels Mar 31, 2026
bug-ops added 2 commits March 31, 2026 22:30
…2542)

Phase 3 fix for elicitation deadlock. run_inline_tool_loop called
execute_tool_call_erased sequentially without draining elicitation_rx,
causing deadlock when an MCP tool sent an elicitation event and blocked
waiting for a response.

- Change run_inline_tool_loop to &mut self
- Wrap each execute_tool_call_erased call in tokio::select! that
  concurrently drains elicitation_rx and calls handle_elicitation_event
- Change handle_elicitation_event to pub(super) for cross-module access
- Add regression test with blocking executor that simulates the real
  MCP deadlock scenario; test times out in 5s if deadlock recurs
@bug-ops bug-ops force-pushed the 2542-elicitation-deadlock branch from d805e32 to 1908fc2 Compare March 31, 2026 20:30
@bug-ops bug-ops enabled auto-merge (squash) March 31, 2026 20:31
@bug-ops bug-ops merged commit 9adcf3a into main Mar 31, 2026
27 checks passed
@bug-ops bug-ops deleted the 2542-elicitation-deadlock branch March 31, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working core zeph-core crate documentation Improvements or additions to documentation rust Rust code changes size/M Medium PR (51-200 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(mcp): elicitation deadlock in run_inline_tool_loop

1 participant