github / github/copilot-cli

`edit` tool silently fails with "No match found" when `old_str` contains CJK typographic quotes

Abierto
#3,254 0 comentarios 0 reacciones 0 asignados Ver en GitHub
area:tools
Lenguaje dominante
Shell
Estrellas
11.2k
Forks
1.9k
Merge medio
14 h 16 min
PR fusionados (30 d)
6

Descripción

### Describe the bug

**Summary**

The `edit` tool returns `No match found` when `old_str` spans a region containing
Unicode typographic (curly) quotation marks — specifically U+201C `\u201c`
(LEFT DOUBLE QUOTATION MARK) and U+201D `\u201d` (RIGHT DOUBLE QUOTATION MARK).
The same edit succeeds when the target region contains only ASCII characters.

### Affected version

v1.0.44

### Steps to reproduce the behavior

**Reproduction**

Given a UTF-8 file `test.md` containing:

```text
Please do not re-examine \u201cwhat repo to change\u201d each time.
```

The following tool call fails:

```json
{
"old_str": "Please do not re-examine \"what repo to change\" each time.",
"new_str": "Please do not re-examine \"what repo to change\" each session."
}
```

Error: `No match found`

### Expected behavior

No error occur, and edit success at the first time.

### Additional context

**Environment**
- GitHub Copilot CLI (terminal coding agent), v1.0.44
- OS: Windows 11, PowerShell 7
- File encoding: UTF-8 LF (no BOM)

**Root cause (hypothesis)**

The LLM generates `old_str` from text it received through the `view` tool.
Typographic quotes (U+201C/U+201D) are visually identical to ASCII `"` (U+0022)
but are distinct Unicode code points. At some stage in the tool-call pipeline —
likely during tokenization or JSON argument serialization — U+201C/U+201D are
normalized to U+0022, causing an exact-match failure against the unmodified file
content.

**Evidence**

- 3/3 edit calls failed where `old_str` overlapped a region containing U+201C/U+201D
- 3/3 edit calls succeeded on the same files where `old_str` avoided those characters
- 100% correlation; no other differing factor (same session, same tool, same model)

**Impact**

- Every `edit` targeting a line with CJK or typographic quotes fails silently
- Error message `No match found` gives no character-level diagnosis
- LLM cannot self-correct without explicit human intervention
- Especially common in East Asian language repositories where typographic quotes
are grammatically standard

**Requested changes**

### 1. Richer error diagnostics (low risk — no behavior change)

When `old_str` is not found, include:
- Line number of the closest substring match
- Character positions that differ
- Unicode code points of mismatched characters
- Hint if the diff involves known typographic/ASCII quote equivalents

Example improved error:
```
Edit failed: old_str not found in file.
Closest match at line 20 (1 character mismatch at position 28):
File: ... \xE2\x80\x9C (U+201C LEFT DOUBLE QUOTATION MARK)
old_str: ... \x22 (U+0022 QUOTATION MARK)
Hint: the file uses typographic quotes. Consider using str.replace() in Python.
```

### 2. Optional quote-folding mode (enhancement — opt-in)

Add an optional `unicode_quote_fold: true` flag that normalizes both `old_str` and
file content through a typographic→ASCII quote mapping before matching (without
altering what is written to disk).

**Workaround (current)**

Use Python `Path.read_text(encoding='utf-8').replace(...).write_text(...)`.
Functional but requires extra steps and is not self-correcting.
```

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.