BUG: asyncio.run() in CLI kills event loop — interview and MCP tools fail #36

Closed
opened 2026-03-14 16:49:42 +00:00 by hermes · 0 comments
Collaborator

Problem

cli.py line 198 uses lambda msg: asyncio.run(chat(msg, session_id="interview")) which calls asyncio.run() per question. This creates and destroys event loops repeatedly. MCP tool subprocesses (Gitea, Filesystem) hold async state that references the first loop — subsequent calls hit "Event loop is closed."

Result: ~50% of interview questions fail. Any CLI command that makes multiple async calls is unreliable.

Root Cause

asyncio.run() is designed to be called once per process. The interview calls it N times in a loop. MCP stdio transports keep references to the first loop.

Files

  • src/timmy/cli.py — lines 184, 198
  • Possibly src/timmy/tools.py — line 538 (same pattern in delegate_task)

Acceptance Criteria

  • timmy interview completes all questions without "Event loop is closed"
  • timmy chat "multi sentence question" works reliably
  • MCP tools (Gitea, Filesystem) work across multiple agent calls in one process
  • No asyncio.run() called more than once per CLI invocation

Approach

Use a single persistent event loop for the CLI process. Either asyncio.get_event_loop().run_until_complete() or refactor to a single asyncio.run(main()) that dispatches all calls.

Priority: HIGH — blocks all other testing

## Problem `cli.py` line 198 uses `lambda msg: asyncio.run(chat(msg, session_id="interview"))` which calls `asyncio.run()` per question. This creates and destroys event loops repeatedly. MCP tool subprocesses (Gitea, Filesystem) hold async state that references the first loop — subsequent calls hit "Event loop is closed." Result: ~50% of interview questions fail. Any CLI command that makes multiple async calls is unreliable. ## Root Cause `asyncio.run()` is designed to be called once per process. The interview calls it N times in a loop. MCP stdio transports keep references to the first loop. ## Files - `src/timmy/cli.py` — lines 184, 198 - Possibly `src/timmy/tools.py` — line 538 (same pattern in delegate_task) ## Acceptance Criteria - [ ] `timmy interview` completes all questions without "Event loop is closed" - [ ] `timmy chat "multi sentence question"` works reliably - [ ] MCP tools (Gitea, Filesystem) work across multiple agent calls in one process - [ ] No `asyncio.run()` called more than once per CLI invocation ## Approach Use a single persistent event loop for the CLI process. Either `asyncio.get_event_loop().run_until_complete()` or refactor to a single `asyncio.run(main())` that dispatches all calls. ## Priority: HIGH — blocks all other testing
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Rockachopa/Timmy-time-dashboard#36