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.
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.
How to fix it
- 01Re-read the file with the read tool first, so any context you add to oldString is verbatim rather than reconstructed.
- 02Expand oldString with more surrounding lines until it appears exactly once in the file.
- 03Or set replaceAll: true when you genuinely want every occurrence of oldString changed, not just one.
- 04For large mechanical rewrites spanning many locations, prefer apply_patch, which anchors on context and line sequences.
- 05Re-run edit and confirm Atlas returns a unified diff for approval rather than Found multiple matches for oldString.
Frequently asked questions
- 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.
Try Atlas in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install AtlasRelated guides
Atlas vs Ellipsis: Terminal AI Coding Agents in 2026
Compare Atlas, a terminal-native AI coding agent with free core and local embeddings, against Ellipsis, a cloud platform with usage-based pricing and live session tracing for 2026.
Atlas with Upstage Solar in 2026
Run Atlas on the Upstage Solar lineup in 2026: solar-pro3 and solar-pro2 at $0.25/$0.25 per Mtok, solar-mini at $0.15/$0.15, across three context sizes.
Self-Review Your Working Diff Before Committing with Atlas (2026 Workflow)
How to self-review your working diff before committing with Atlas in 2026: bash produces the diff, read checks each file, grep finds leftovers, session revert undoes bad edits.
Atlas with Qwen2.5-Coder 32B (Ollama): the air-gapped ceiling in 2026
Qwen2.5-Coder 32B (Ollama) in Atlas: 20GB of weights, roughly 22GB to serve on a 24GB card, 32K tokens (32,768) of context, Free (self-hosted), fully air-gapped.
Atlas with DeepCoder 14B (Ollama): RL-Tuned for First-Attempt Diffs in 2026
DeepCoder 14B (Ollama) is a 9.0GB RL-tuned coder with a 128K context, built for first-attempt correctness. Free (self-hosted). Atlas setup and tradeoffs for 2026.
Atlas with DeepSeek V3 (open weights): The Frozen 671B Baseline in 2026
Run Atlas on DeepSeek V3 (open weights) in 2026. DeepInfra hosts the MIT-licensed 671B MoE at $0.32 per Mtok input, $0.89 per Mtok output, 128K context.
Atlas vs PearAI: Choosing Your AI Coding Agent in 2026
Compare Atlas, the terminal-native AI coding agent, with PearAI, a VS Code fork. Evaluate features, pricing, and community support for developers in 2026.
Atlas vs Tabnine: Choosing Your Terminal AI Coding Agent in 2026
Comparing Atlas and Tabnine for developers in 2026. Atlas offers a terminal-native AI agent with diff review, while Tabnine provides privacy-first code completion and chat.