Tools Fail to Unescape XML Entities (e.g., "&&" Becomes Invalid Shell Syntax) #2991

Closed
opened 2026-02-16 17:38:09 -05:00 by yindo · 7 comments
Owner

Originally created by @taqtiqa-mark on GitHub (Nov 20, 2025).

Originally assigned to: @rekram1-node on GitHub.

Description

Disclosure: 1st draft AI generated.

Tool fail to properly unescape XML entities in command arguments, leading to execution errors, or file content corruption. This occurs when commands include chained operators like "&&", which must be escaped as "&&" in the XML function call format to make it valid XML. However, the tool passes the escaped string directly to the shell without unescaping, causing syntax errors.

Also happens with Edit and Write tools where \n replaces newlines and a whole file becomes one line of text.

Environment:

  • Platform: Linux.
  • Tools: Bash, Write, Edit tools in opencode.

Impact:

  • Prevents reliable use of chained Bash commands, breaking workflows like script execution or multi-step operations.

Suggested Fix:

  • In the Tool handlers, add unescaping logic (e.g., replace "&" with "&", "\n" with new line, etc.) before executing the command string in the shell. Reference standard XML entity handling in tool parsers.

Additional Context:

  • This aligns with the safety instructions' XML-inspired format, but the parsing layer appears to miss unescaping.
  • Reproducible in sessions with function calls: Bash, Write, Edit.

Related:
https://github.com/sst/opencode/issues/3868#issuecomment-3522364197

OpenCode version

1.0.77

Steps to reproduce

  1. Invoke the Bash tool with a command like: cd /path && ls (escaped for XML validity).
  2. The tool executes it as "cd /path && ls" in the shell.
  3. Result: Error like "/bin/sh: 1: Syntax error: "&" unexpected".

Expected Behavior:

  • The app should unescape the argument (e.g., "&&" -> "&&") before passing to the shell, allowing valid execution (e.g., "cd /path && ls").

Actual Behavior:

  • Escaped string is passed literally, causing shell syntax errors for any command with "&" (e.g., chaining with "&&").

Screenshot and/or share link

No response

Operating System

Linux

Terminal

Alacritty & Zellij

Originally created by @taqtiqa-mark on GitHub (Nov 20, 2025). Originally assigned to: @rekram1-node on GitHub. ### Description Disclosure: 1st draft AI generated. Tool fail to properly unescape XML entities in command arguments, leading to execution errors, or file content corruption. This occurs when commands include chained operators like "&&", which must be escaped as "&&" in the XML function call format to make it valid XML. However, the tool passes the escaped string directly to the shell without unescaping, causing syntax errors. Also happens with Edit and Write tools where `\n` replaces newlines and a whole file becomes one line of text. **Environment:** - Platform: Linux. - Tools: Bash, Write, Edit tools in opencode. **Impact:** - Prevents reliable use of chained Bash commands, breaking workflows like script execution or multi-step operations. **Suggested Fix:** - In the Tool handlers, add unescaping logic (e.g., replace "&" with "&", "\n" with new line, etc.) before executing the command string in the shell. Reference standard XML entity handling in tool parsers. **Additional Context:** - This aligns with the safety instructions' XML-inspired format, but the parsing layer appears to miss unescaping. - Reproducible in sessions with function calls: Bash, Write, Edit. **Related:** https://github.com/sst/opencode/issues/3868#issuecomment-3522364197 ### OpenCode version 1.0.77 ### Steps to reproduce 1. Invoke the Bash tool with a command like: `cd /path && ls` (escaped for XML validity). 2. The tool executes it as "cd /path && ls" in the shell. 3. Result: Error like "/bin/sh: 1: Syntax error: "&" unexpected". **Expected Behavior:** - The app should unescape the argument (e.g., "&&" -> "&&") before passing to the shell, allowing valid execution (e.g., "cd /path && ls"). **Actual Behavior:** - Escaped string is passed literally, causing shell syntax errors for any command with "&" (e.g., chaining with "&&"). ### Screenshot and/or share link _No response_ ### Operating System Linux ### Terminal Alacritty & Zellij
yindo added the bug label 2026-02-16 17:38:09 -05:00
yindo closed this issue 2026-02-16 17:38:09 -05:00
Author
Owner

@taqtiqa-mark commented on GitHub (Nov 20, 2025):

Another example:

$ cat <<'EOF' > /home/node/project/tmp/024-analysis/024-analysis-report.md
...
/bin/sh: 1: Syntax error: "&" unexpected
@taqtiqa-mark commented on GitHub (Nov 20, 2025): Another example: ```shell $ cat <<'EOF' > /home/node/project/tmp/024-analysis/024-analysis-report.md ... /bin/sh: 1: Syntax error: "&" unexpected ```
Author
Owner

@rekram1-node commented on GitHub (Nov 20, 2025):

we shall fix

@rekram1-node commented on GitHub (Nov 20, 2025): we shall fix
Author
Owner

@taqtiqa-mark commented on GitHub (Nov 27, 2025):

Hmm, it appears that most failures occur silently, and occasionally you get an error report in the TUI. Mostly the effect can look like the LLM failed to follow an instruction, e.g. save a file containing the output.

@taqtiqa-mark commented on GitHub (Nov 27, 2025): Hmm, it appears that most failures occur silently, and occasionally you get an error report in the TUI. Mostly the effect can look like the LLM failed to follow an instruction, e.g. save a file containing the output.
Author
Owner

@taqtiqa-mark commented on GitHub (Dec 28, 2025):

we shall fix

Still seen in v1.0.193

@taqtiqa-mark commented on GitHub (Dec 28, 2025): > we shall fix Still seen in v1.0.193
Author
Owner

@taqtiqa-mark commented on GitHub (Dec 28, 2025):

Root cause:

Custom XML parser extracts textContent literally (no entity decoding like &→& or \n→newline), passing raw strings directly to child_process.spawn(command) in bash tool and string ops/Bun.write in edit/write tools.

Files:

  • packages/opencode/src/tool/bash.ts (line ~170: spawn(params.command, { – no unescape)
  • packages/opencode/src/tool/edit.ts (uses raw params.oldString/newString)
  • packages/opencode/src/tool/registry.ts (registers tools)
@taqtiqa-mark commented on GitHub (Dec 28, 2025): Root cause: Custom XML parser extracts <parameter> textContent literally (no entity decoding like \&amp;→& or \\n→newline), passing raw strings directly to child_process.spawn(command) in bash tool and string ops/Bun.write in edit/write tools. Files: - packages/opencode/src/tool/bash.ts (line ~170: spawn(params.command, { – no unescape) - packages/opencode/src/tool/edit.ts (uses raw params.oldString/newString) - packages/opencode/src/tool/registry.ts (registers tools)
Author
Owner

@taqtiqa-mark commented on GitHub (Dec 28, 2025):

@rekram1-node, will you accept PR that use either fast-xml-parser, xml2js or xmldom, xpath, etc. Or is there a preferred approach?

@taqtiqa-mark commented on GitHub (Dec 28, 2025): @rekram1-node, will you accept PR that use either `fast-xml-parser`, `xml2js` or `xmldom`, `xpath`, etc. Or is there a preferred approach?
Author
Owner

@taqtiqa-mark commented on GitHub (Feb 12, 2026):

In the spirit of calling out excellent engineering and design....

I've found that the Pi Coding Agent is more robust and, for me has none of the issues that I've encountered in OC, or has an elegant way to resolve them.... I'm dropping out of OC issues:

@taqtiqa-mark commented on GitHub (Feb 12, 2026): In the spirit of calling out excellent engineering and design.... I've found that the Pi Coding Agent is more robust and, for me has none of the issues that I've encountered in OC, or has an elegant way to resolve them.... I'm dropping out of OC issues: - [Pi Coding Agent](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent) - [Overview](https://mariozechner.at/posts/2025-11-30-pi-coding-agent/) - [Example development session](https://www.youtube.com/watch?v=ANQ1IYsFM2s)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#2991