Skip to content

Unhandled treesit-query-error in pi-coding-agent--markdown-visible-string crashes table rendering mid-stream #186

@DevGiuDev

Description

@DevGiuDev

When pi-coding-agent renders a streaming response containing a Markdown table with cells that include inline markup (e.g. 🛒 **Marketplace**), it calls font-lock-ensure on a temporary md-ts-mode buffer. If md-ts-mode's tree-sitter font-lock rules throw a treesit-query-error, the exception propagates uncaught up through the streaming render pipeline, breaking the rest of the response display.

The user sees the response truncated mid-table, with subsequent content missing from the chat buffer.


Environment

Emacs 30.2
pi-coding-agent 20260405.21
md-ts-mode 20260309.11
tree-sitter system library 0.26.8
Model glm-5.1 via ZAI (openai-completions provider)

Steps to Reproduce

  1. Start a new pi-coding-agent chat session with a model that produces rich Markdown tables (e.g. glm-5.1 via ZAI).
  2. Send a prompt that triggers a response containing a table with bold text or emoji in cells:
Search for a file in ~/dev/myproject/, read it, and summarize it.
  1. Observe the response is cut off mid-table in the chat buffer.
  2. Check *Messages* for the error — with debug-on-error t the full backtrace is:
Debugger entered--Lisp error: (treesit-query-error "Syntax error at" 136
  "(block_quote) @md-ts-block-quote ..."
  "Debug the query with `treesit-query-validate'")
  treesit--font-lock-fontify-region-1(...)
  treesit-font-lock-fontify-region(1 18 nil)
  font-lock-ensure()
  pi-coding-agent--markdown-visible-string("🛒 **Marketplace**")
  pi-coding-agent--table-display-groups(...)
  pi-coding-agent--decorate-table(...)
  pi-coding-agent--maybe-decorate-streaming-table()
  pi-coding-agent--display-message-delta(" |\n")
  pi-coding-agent--handle-display-event(...)

Root Cause

pi-coding-agent--markdown-visible-string (in pi-coding-agent-table.el) creates a persistent buffer in md-ts-mode and calls font-lock-ensure to extract the visible text of a table cell:

(defun pi-coding-agent--markdown-visible-string (markdown)
  ...
  (with-current-buffer (pi-coding-agent--visible-string-buffer)
    (let ((inhibit-read-only t))
      (erase-buffer)
      (insert markdown))
    (font-lock-ensure)          ; <-- can throw treesit-query-error
    (pi-coding-agent--visible-text (point-min) (point-max))))

font-lock-ensure is called without any error handling. When md-ts-mode's paragraph/prepend tree-sitter query fails at the C level (a known incompatibility between Emacs 30 treesit.c generating #match and tree-sitter 0.25+ requiring #match?), the exception escapes into pi-coding-agent--display-message-delta, silently aborting the render of the current and all subsequent streaming deltas.

Note: the same treesit-query-error also appears as Error during redisplay: (jit-lock-function ...) in the main chat buffer — that is a separate manifestation of the same md-ts-mode query bug (reported independently at https://github.com/dnouri/md-ts-mode/issues/XXX).


Proposed Fix

Wrap font-lock-ensure in a condition-case and fall back to returning the raw markdown string on error. This makes the function resilient to any font-lock failure, not just this specific md-ts-mode query issue:

(defun pi-coding-agent--markdown-visible-string (markdown)
  ...
  (with-current-buffer (pi-coding-agent--visible-string-buffer)
    (let ((inhibit-read-only t))
      (erase-buffer)
      (insert markdown))
    ;; Guard against treesit-query-error or other font-lock failures
    ;; (e.g. md-ts-mode query incompatibility with tree-sitter 0.25+).
    ;; On failure, fall back to the raw markdown string.
    (condition-case _err
        (font-lock-ensure)
      (error nil))
    (pi-coding-agent--visible-text (point-min) (point-max))))

The fallback is safe: pi-coding-agent--visible-text still returns a reasonable string (the raw markdown with delimiters visible), which is better than crashing the render pipeline entirely.


Additional Notes

  • The bug is not model-specific in principle, but in practice it is triggered more frequently by models like glm-5.1 (ZAI) that tend to produce tables with rich inline markup (bold + emoji) in cells. Models that generate plain-text table cells never hit this code path.
  • The treesit-query-error only fires when md-ts-mode is the active mode in the fontification buffer and the installed tree-sitter library is 0.25+. Users on older tree-sitter versions are unaffected.
  • A fix to md-ts-mode itself (removing the broken :match predicate) eliminates the root cause entirely. This defensive fix in pi-coding-agent is recommended regardless, as it protects against any future font-lock errors from any mode used in the fontification buffer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions