charmbracelet/crush · error
old_string appears multiple times in the file. Please provid
Error message
old_string appears multiple times in the file. Please provide more context to ensure a unique match, or set replace_all to true
What it means
findAndReplace requires old_string to occur exactly once in the file when replace_all is false. If strings.Index and strings.LastIndex disagree, the string occurs multiple times and this guard rejects the edit rather than making an ambiguous replacement. It is a deliberate safety check against unintended mass edits.
Source
Thrown at internal/agent/tools/edit.go:212
// findAndReplace performs a find-and-replace on content. When replaceAll is
// false it requires exactly one match. If an exact match fails, it falls back
// to whitespace-normalized matching and, failing that, returns a diagnostic
// hint describing why the replacement could not be made. The returned boolean
// reports whether the replacement relied on the whitespace-normalized
// fallback rather than an exact match.
func findAndReplace(content, old, new string, replaceAll bool) (string, bool, error) {
if replaceAll {
if strings.Contains(content, old) {
return strings.ReplaceAll(content, old, new), false, nil
}
} else {
index := strings.Index(content, old)
switch {
case index == -1:
// Fall through to the fuzzy fallback below.
case index != strings.LastIndex(content, old):
return "", false, fmt.Errorf("old_string appears multiple times in the file. Please provide more context to ensure a unique match, or set replace_all to true")
default:
return content[:index] + new + content[index+len(old):], false, nil
}
}
if result, ok := normalizedReplace(content, old, new, replaceAll); ok {
return result, true, nil
}
return "", false, notFoundError(content, old)
}
// withWhitespaceNote appends the whitespace auto-correction note to a tool
// response message when the edit did not match the file byte-for-byte.
func withWhitespaceNote(message string, whitespaceCorrected bool) string {
if !whitespaceCorrected {
return message
}
return message + "\n" + whitespaceCorrectedNoteView on GitHub (pinned to 7944b8e522)
Solutions
- Expand old_string to include surrounding unique context (more lines, distinctive tokens).
- Set replace_all to true if every occurrence should be replaced.
- Split the edit into multiple calls, each targeting one unique occurrence.
- Re-read the file (View tool) to copy exact text including indentation, then retry.
Example fix
// before
{"old_string": "return nil", "new_string": "return err"}
// after: include unique context
{"old_string": "if err != nil {\n\treturn nil\n}", "new_string": "if err != nil {\n\treturn err\n}", "replace_all": false} Defensive patterns
Strategy: validation
Validate before calling
func isUniqueEnough(content, old string) bool {
if strings.Count(content, old) != 1 {
return false
}
return true
}
// gate the tool call:
// if !isUniqueEnough(fileContent, oldString) { set replace_all or extend context } Try / catch
if strings.Contains(err.Error(), "appears multiple times") {
// widen old_string with surrounding lines, or set replace_all: true, and retry
} Prevention
- Include 2-3 lines of surrounding context in old_string, not one-liners.
- Never use bare braces, imports, or identifiers as old_string.
- Copy old_string verbatim from a fresh View of the file.
- Set replace_all:true deliberately when replacing every occurrence.
When it happens
Trigger: Calling the edit tool with an old_string that matches 2+ locations in the file while replace_all is false — typically because the snippet is too short or generic (e.g. a closing brace, a repeated import line, an identifier alone on a line).
Common situations: Model-supplied edits using short common snippets, refactors where the same pattern appears in several functions, CRLF vs LF mismatches after whitespace normalization changing match counts.
Related errors
- prompt is required
- session id missing from context
- agent message id missing from context
- invalid client_id
- not a valid bedrock api key
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/c62087d3d76d16e1.
Report an issue: GitHub.