# Atlas edit error: Found multiple matches for oldString

> Expand oldString with more surrounding lines until it appears exactly once, or set replaceAll: true when you genuinely want every occurrence changed.

Atlas fails with Found multiple matches for oldString because edit.replace requires the match to be unique unless replaceAll is set: it compares indexOf against lastIndexOf and rejects the edit when the two differ, so the fix is to expand oldString with more surrounding lines until the span appears exactly once in the file. If you genuinely want every occurrence changed, set replaceAll: true and Atlas will apply the replacement to all of them. Re-read the file first with the read tool so the context you add is verbatim rather than reconstructed. For large mechanical rewrites across many hunks, prefer apply_patch, which anchors on context and line sequences instead of a single unique string.

## Symptom

The edit tool fails with: Found multiple matches for oldString. Provide more surrounding context to make the match unique.

## Cause

Unless replaceAll is set, edit.replace requires the match to be unique: it compares indexOf against lastIndexOf and rejects the edit when they differ.

## Fix

1. Re-read the file with the read tool first, so any context you add to oldString is verbatim rather than reconstructed.
2. Expand oldString with more surrounding lines until it appears exactly once in the file.
3. Or set replaceAll: true when you genuinely want every occurrence of oldString changed, not just one.
4. For large mechanical rewrites spanning many locations, prefer apply_patch, which anchors on context and line sequences.
5. Re-run edit and confirm Atlas returns a unified diff for approval rather than Found multiple matches for oldString.

## Why does Atlas say it found multiple matches for oldString

Atlas reports Found multiple matches for oldString because edit.replace enforces a uniqueness check. Unless replaceAll is set, edit.replace compares 2 positions, indexOf and lastIndexOf, and rejects the edit whenever they differ, which is exactly the condition of the text appearing more than once in the file.

The check is a safety property, not a limitation. An edit that could land in two places is an edit whose outcome you cannot predict from the arguments alone, and Atlas refuses to guess which occurrence you meant. Ambiguous oldStrings are extremely common in real code: a closing brace, a return statement, an import line, a repeated field assignment inside two similar structs. Any of these can occur dozens of times in one file. The indexOf against lastIndexOf comparison is a cheap, exact test for that ambiguity, and it runs before anything is written. Nothing was modified when this error fired.

## How to make oldString unique for an Atlas edit

Make oldString unique by expanding it with more surrounding lines until the span appears exactly 1 time. Atlas edit needs indexOf and lastIndexOf to agree, so adding the enclosing function signature, the preceding declaration, or the following line is usually enough to collapse many candidate matches down to one.

Choose context that is genuinely distinguishing rather than merely longer. Adding three more blank lines around a repeated statement does not help if those blank lines also repeat. Adding the function name that encloses the statement almost always does, because function names are unique within a file far more often than statement bodies are. Re-read the file with the read tool before you expand, so the lines you add are verbatim and not reconstructed, since a context line that is off by one character turns a multiple-match failure into a not-found failure and you have traded one error for another.

## When to set replaceAll: true in an Atlas edit

Set replaceAll: true on an Atlas edit when you genuinely want every occurrence of oldString changed. With replaceAll set, edit.replace skips the check that compares indexOf against lastIndexOf, applies the replacement to all matches, and needs 0 extra context lines from you. That is exactly right for a rename.

replaceAll is the correct tool for a specific shape of change: a mechanical substitution where every instance should become the same new text. Renaming a local variable throughout a file, updating a repeated import path, or changing a repeated string literal all fit. Be deliberate, though, because replaceAll removes the very check that just protected you. If some occurrences of oldString should change and others should not, replaceAll will happily rewrite all of them, and you will only notice when you read the diff. Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so read that diff carefully whenever replaceAll is set.

## When to use apply_patch instead of an Atlas edit

For large mechanical rewrites, prefer apply_patch over Atlas edit. apply_patch anchors on context and line sequences rather than on 1 unique string, so a change touching many separate hunks does not require you to construct an enormous, unambiguous oldString for each of them.

The distinction is about the shape of the change. Atlas edit is built around one targeted replacement of a uniquely identified span, and its uniqueness check exists to keep that contract honest. When a refactor spans a dozen regions of a file, forcing it through edit means a dozen separate oldStrings, each of which has to survive the indexOf and lastIndexOf test, and each of which is a chance to hit Found multiple matches for oldString. apply_patch is designed for that case and anchors differently. Reach for apply_patch when the change is broad and structural, and keep edit for the surgical single-span replacement it is good at.

## How to verify the Atlas edit matched exactly once

Verify by re-running the edit after expanding oldString. A unique match produces 1 unified diff for approval, because Atlas computes a unified diff for every file edit and surfaces it before writing. Seeing Found multiple matches for oldString again means indexOf and lastIndexOf still disagree.

The diff is the real verification, and it is worth actually reading rather than approving on reflex. Confirm that the hunk Atlas is proposing sits in the region you intended, not in a similar-looking block elsewhere in the file, because a span can be unique and still be the wrong span. If you used replaceAll: true, the diff will show every location that changed, and that list is exactly what you should audit before approving. Atlas snapshots file changes as git patches, so an edit that lands in places you did not intend can be diffed and rolled back after the fact.

## FAQ

### how do I fix found multiple matches for oldString in Atlas

Expand oldString with more surrounding lines until the span appears exactly once in the file. Atlas edit compares indexOf against lastIndexOf and rejects the edit when they differ, so a unique span is what the check is looking for.

### what does replaceAll do in the Atlas edit tool

Setting replaceAll: true tells Atlas edit to change every occurrence of oldString. With replaceAll set, edit.replace skips the indexOf against lastIndexOf uniqueness check and applies the replacement to all matches.

### why does Atlas edit require a unique oldString

An oldString that appears twice makes the outcome of the edit unpredictable from the arguments alone, so Atlas refuses to guess. edit.replace compares indexOf against lastIndexOf and rejects the edit when the two positions differ.

### what context should I add to make an Atlas oldString unique

Add genuinely distinguishing context, such as the enclosing function signature or the preceding declaration. More blank lines do not help if they also repeat. Re-read the file with the read tool first so the added lines are verbatim.

### should I use apply_patch or edit for a big refactor in Atlas

Use apply_patch for large mechanical rewrites. apply_patch anchors on context and line sequences, so a change touching many hunks does not require constructing a uniquely matching oldString for each one.

### is replaceAll safe to use in Atlas

replaceAll is safe when every occurrence genuinely should change, such as a local rename. It removes the uniqueness check, so if some occurrences should stay, they will be rewritten too. Read the unified diff Atlas surfaces before approving.

### does Atlas modify the file when the multiple matches error fires

No. The uniqueness check in edit.replace runs before any write, so Found multiple matches for oldString means nothing was changed on disk. Expand oldString or set replaceAll: true and try again.

---

Canonical HTML: https://runatlas.sh/resources/troubleshooting/edit-multiple-matches
Source of truth: aeo_pages row `/resources/troubleshooting/edit-multiple-matches` (segment: Troubleshooting) (this file is generated from it, never hand-edited).
Licence: Atlas is proprietary with a free core. It is not open source and there is no public source repository.
