#14470: fix(agents): unescape newlines in write and edit tool content
agents
size: XS
Cluster:
Error Handling in Agent Tools
# Summary
Unescape literal \n, \r\n, and \r in write/edit tool arguments to handle models that double-escape tool call content.
# Problem
Some models (like Grok) or providers/proxies occasionally send tool calls where newlines are escaped as literal strings (e.g., "Line1\nLine2"). The write tool writes these characters as-is, corrupting code and documentation files.
# Changes
- Extended `RequiredParamGroup` to support an `unescape` flag.
- Enabled `unescape` for `write.content`, `edit.oldText`, and `edit.newText`.
- Implemented robust newline unescaping in `wrapToolParamNormalization` to convert \r\n, \r, and \n to real newlines.
# Validation
- Verified with a local reproduction unit test using both real newlines and literal \n sequences.
- Confirmed existing agent tests pass.
# Risk & Rollback
- Low risk. Only affects tools wrapped with param normalization and specific keys.
- Revert by undoing the unescape logic in `src/agents/pi-tools.read.ts`.
Fixes #14452
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the agent tool parameter normalization layer (`src/agents/pi-tools.read.ts`) to handle providers/models that double-escape tool call strings. It extends `RequiredParamGroup` with an `unescape` flag and enables it for `write.content` and `edit.oldText`/`edit.newText`, then performs newline normalization in `wrapToolParamNormalization` before required-param validation and tool execution. This ensures `\\n` sequences don’t get written literally into files when the model escapes newlines in tool arguments.
<h3>Confidence Score: 4/5</h3>
- Safe to merge after fixing the CR unescape gap for double-escaped CRLF/CR.
- Change is localized to tool param normalization for write/edit and is unlikely to affect other behaviors, but the stated goal includes literal \r\n/\r handling and the current implementation only unescapes literal \\n, leaving a real correctness gap for providers that escape CRLF/CR.
- src/agents/pi-tools.read.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#9861: fix(agents): re-run tool_use/tool_result repair after limitHistoryT...
by CyberSinister · 2026-02-05
75.9%
#3647: fix: sanitize tool arguments in session history
by nhangen · 2026-01-29
75.9%
#10189: fix: resolve file_path param in tool display for read/write tools
by Yida-Dev · 2026-02-06
75.4%
#12487: fix(agents): strip orphaned tool_result when tool_use is sanitized ...
by skylarkoo7 · 2026-02-09
74.7%
#12608: fix: sanitize client tool call IDs per provider requirements
by piyushhhxyz · 2026-02-09
74.4%
#13831: fix(agents): include Anthropic in tool call ID sanitization
by lailoo · 2026-02-11
74.4%
#21166: fix(agents): sanitize tool names in session transcript repair (#8595)
by dinakars777 · 2026-02-19
73.7%
#11453: fix: apply normalizeToolName() at all tool lookup points
by sypsyp97 · 2026-02-07
73.4%
#19094: Fix empty tool_call_id and function names in provider transcript pa...
by yxshee · 2026-02-17
73.3%
#7525: Agents: skip errored tool calls during pairing
by justinhuangcode · 2026-02-02
73.3%