ITADN

A0 CLI crashes with Rich/Textual MarkupError when chat log contains path-like bracket markup

#1606Openncc1701dhs 创建于 2026-05-05
N
ncc1701dhscommented
## Summary The macOS A0 CLI crashes while rendering or handling chat/context events when the chat log contains path-like text that appears to be interpreted as Rich/Textual markup. The first visible error is a `MarkupError` caused by a string such as `[/a0/tests/test_a0_connector_prompt_gatin]` being interpreted as a closing Rich markup tag. After that, the CLI repeatedly raises `textual.css.query.NoMatches` because `#chat-log` can no longer be found on the active screen. This appears to be a local A0 CLI UI/rendering issue, not a Caddy, HTTPS, or WebSocket transport issue. --- ## Environment | Item | Value | |---|---| | Client OS | macOS | | CLI package | `agent_zero_cli` | | Python runtime | Python 3.11 | | CLI path shown in traceback | `/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/agent_zero_cli/...` | | Agent Zero server | Docker/Linux container | | Access URL / FQDN | `https://ai-agent.ailab.tokyo` | | Reverse proxy | Caddy | | Connector transport | HTTP + WebSocket / Socket.IO | | A0 connector API | `/api/plugins/_a0_connector/v1/capabilities` | --- ## What was confirmed The connector capability endpoint responds successfully over HTTPS through Caddy. ```http POST https://ai-agent.ailab.tokyo/api/plugins/_a0_connector/v1/capabilities HTTP/2 200 ``` The returned capabilities include: ```json { "protocol": "a0-connector.v1", "auth": ["session"], "auth_required": true, "transports": ["http", "websocket"], "streaming": true, "websocket_namespace": "/ws", "websocket_handlers": ["plugins/_a0_connector/ws_connector"], "features": [ "chat_create", "chats_list", "chat_get", "message_send", "log_tail", "projects", "text_editor_remote", "code_execution_remote", "computer_use_remote", "remote_file_tree" ] } ``` The Web UI WebSocket also appears to work through Caddy. Browser DevTools showed frames like: ```text 42/ws,["state_push",{"handlerId":"ws_webui.WsWebui", ... }] ``` So the issue does not appear to be a general HTTPS/WSS/Caddy forwarding failure. --- ## Actual behavior After receiving/rendering chat log content that included long paths and bracket-like strings, the A0 CLI printed the following error: ```text MarkupError: closing tag '[/a0/tests/test_a0_connector_prompt_gatin]' does not match any open tag ``` Then repeated task exceptions appeared: ```text Task exception was never retrieved future: <Task finished name='Task-5678' coro=<AsyncClient._handle_eio_message() done, defined at /Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/socketio/async_client.py:563> exception=NoMatches("No nodes match '#chat-log' on Screen(id='_default')")> Traceback (most recent call last): File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/socketio/async_client.py", line 580, in _handle_eio_message await self._handle_event(pkt.namespace, pkt.id, pkt.data) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/socketio/async_client.py", line 417, in _handle_event r = await self._trigger_event(data[0], namespace, *data[1:]) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/socketio/async_client.py", line 472, in _trigger_event ret = await handler(*args) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/agent_zero_cli/client.py", line 381, in _on_context_event callback(self._unwrap_envelope(payload)) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/agent_zero_cli/connection.py", line 240, in <lambda> app.client.on_context_event = lambda data: app._run_on_ui(app._handle_context_event, data) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/agent_zero_cli/app.py", line 909, in _run_on_ui func(*args) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/agent_zero_cli/app.py", line 1051, in _handle_context_event event_handlers.handle_context_event(self, data) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/agent_zero_cli/event_handlers.py", line 78, in handle_context_event log = app.query_one("#chat-log", ChatLog) File "/Users/ncc1701dhs/.local/share/uv/tools/a0/lib/python3.11/site-packages/textual/dom.py", line 1505, in query_one raise NoMatches(f"No nodes match {query_selector!r} on {base_node!r}") textual.css.query.NoMatches: No nodes match '#chat-log' on Screen(id='_default') ``` The `NoMatches('#chat-log')` exception repeats for subsequent context events. --- ## Expected behavior The CLI should display chat/log content as literal text, even if it contains strings like: ```text [/a0/tests/test_a0_connector_prompt_gating.py] /a0/plugins/_a0_connector/... ``` Such content should not be interpreted as Rich/Textual markup. The CLI should not crash, and context event handling should continue normally. --- ## Suspected cause The CLI appears to pass chat/log content to Rich/Textual without escaping markup-sensitive characters. A path-like or log-like string containing square brackets may be interpreted as Rich markup. In this case, a substring like: ```text [/a0/tests/test_a0_connector_prompt_gatin] ``` seems to be parsed as a closing tag, causing: ```text rich.errors.MarkupError: closing tag ... does not match any open tag ``` After the initial render failure, the Textual screen/component tree appears to enter an invalid state, causing `app.query_one("#chat-log", ChatLog)` to fail with: ```text NoMatches("No nodes match '#chat-log' on Screen(id='_default')") ``` --- ## Why this looks like a CLI rendering issue, not a transport issue The following transport checks were successful: - HTTPS endpoint through Caddy returns `HTTP/2 200`. - Connector capabilities include `http` and `websocket` transports. - Web UI WebSocket frames are visible, including `state_push` from `ws_webui.WsWebui`. - The CLI shows connection to the expected host: `https://ai-agent.ailab.tokyo`. Therefore, the WebSocket/Caddy path appears functional. The crash happens in the local CLI UI stack while handling/rendering context events. --- ## Possible fix Escape chat/log/message content before rendering it with Rich/Textual. For example, use Rich markup escaping around any untrusted or server-provided text before passing it to a Rich renderable: ```python from rich.markup import escape safe_text = escape(raw_text) ``` Any content from chat messages, logs, tool output, file paths, traceback text, and server-sent context events should be treated as untrusted display text unless intentionally formatted. Also, `handle_context_event()` could defensively handle the case where `#chat-log` is not mounted yet or no longer exists, instead of allowing repeated uncaught task exceptions. Potential places from the traceback: ```text agent_zero_cli/event_handlers.py:78 agent_zero_cli/app.py:1051 agent_zero_cli/app.py:909 agent_zero_cli/connection.py:240 agent_zero_cli/client.py:381 ``` --- ## Workaround Temporary workarounds: 1. Restart the A0 CLI fully. 2. Avoid opening the affected chat/context in the CLI if it contains the problematic log text. 3. Use a new chat/context after restarting the CLI. 4. Avoid sending very long raw logs or path-heavy output to the CLI until the rendering is fixed. 5. Use the Web UI to inspect the problematic chat if the CLI crashes during render. --- ## Additional context This was observed while debugging A0 CLI Connector remote tool exposure. Remote file-tree or connector metadata may appear, but `code_execution_remote`, `text_editor_remote`, or `computer_use_remote` may not become usable if the CLI UI crashes while processing context events. A search did not find an exact existing Agent Zero issue for this `MarkupError` + `#chat-log` combination. Similar Rich CLI crashes caused by unescaped bracketed text have been reported in other CLI projects, so this may be a general Rich/Textual escaping issue pattern. --- ## Short version for maintainers A0 CLI should probably escape untrusted chat/log output before rendering with Rich/Textual. A path-like string was interpreted as a Rich closing tag, causing `MarkupError`, after which the CLI repeatedly failed to find `#chat-log` while handling Socket.IO context events.
2 条评论