From 6b4337bfe227d51aad2c2f982d56a1089279d5b3 Mon Sep 17 00:00:00 2001 From: tomekpanek Date: Wed, 3 Jun 2026 22:20:55 +0200 Subject: [PATCH] fix(chat): restore fenced code blocks (placeholder used escaped backslashes) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit renderChatContent extracts ```fenced``` blocks and replaces each with a sentinel containing literal NULL bytes: return `\x00CODE${id}\x00`; // \x00 = one byte (U+0000) The restore step then searched for a literal-text version of the same string: html.replace(`\\x00CODE${i}\\x00`, '
...
'); ^^ ^^ in a template literal these are backslash + 'x' + '0' + '0', not the U+0000 escape. So the search needle never matched the sentinel actually present in `html`. The unreplaced sentinel reached `element.innerHTML = ...`; per the HTML spec the parser drops U+0000 characters, leaving the visible text "CODE0", "CODE1", … inside the message. Repro: 1. Have Hermes return any reply containing a ```fenced``` code block 2. Notice the rendered bubble shows "CODE0" instead of the code 3. Confused users then ask the model what CODE0 means; the model has no idea and starts hallucinating explanations Fix: drop the extra backslashes so the needle is the same NULL-bracketed sentinel that was inserted in step 1. --- src/js/chat/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/chat/cli.js b/src/js/chat/cli.js index b91b8c0..881d2f4 100644 --- a/src/js/chat/cli.js +++ b/src/js/chat/cli.js @@ -186,7 +186,7 @@ function renderChatContent(text) { // Use unique placeholder so we can find it after innerHTML const placeholder = `__CODE_CONTENT_${i}__`; html = html.replace( - `\\x00CODE${i}\\x00`, + `\x00CODE${i}\x00`, `
${langLabel}${placeholder}
` ); });