-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Bug Description
Streaming chat crashes with two linked errors:
- Marko markdown rendering fails with "Unsupported renderer"
- Async cleanup crashes with "Attempted to exit cancel scope in a different task"
Error Messages
Streaming error: Unsupported renderer <class 'marko._Renderer'>
Error: Unsupported renderer <class 'marko._Renderer'>
[error] Streaming failed: Attempted to exit cancel scope in a different task than it was entered in
Followed by full crash with asyncio.exceptions.CancelledError.
Steps to Reproduce
- Start interactive chat:
my-app ai chat - Switch to a model like
gpt-5-mini:/model gpt-5-mini - Send a message that generates a response with certain markdown elements
- Chat crashes with the above errors
Root Cause Analysis
Issue 1: Marko Renderer
The custom TerminalRenderer in app/cli/marko_terminal_renderer.py may not have handlers for all markdown element types. When marko encounters an element without a matching render_* method, it falls back to the default _Renderer which throws the error.
Likely missing renderers for:
- Certain GFM elements (task lists, strikethrough, etc.)
- Edge case elements the AI generated
Issue 2: Cancel Scope Crossing
When the marko error occurs mid-stream:
- The streaming async generator is interrupted
- pydantic_ai's streaming cleanup runs via
cancel_and_wait_for_background_tasks() - The cancel scope was entered in one task but exits in another
- This is a known anyio/pydantic_ai interaction issue
Files Involved
app/cli/marko_terminal_renderer.py- Custom renderer (needs more element handlers)app/cli/ai_rendering.py- Streaming rendererapp/services/ai/service.py-stream_chat()methodapp/cli/ai.py- Interactive chat loop
Suggested Fix
- Add fallback handling in TerminalRenderer - Catch unknown elements and render as plain text instead of crashing
- Wrap streaming in try/except - Gracefully handle rendering errors without crashing the whole session
- Consider anyio compatibility - May need to ensure cancel scopes don't cross task boundaries
Context
Error occurred after switching models mid-session. The AI response contained markdown that triggered the renderer issue.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working