Troubleshooting

Atlas edit error: Found multiple matches for oldString

Updated 7 min read

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

  1. 01Re-read the file with the read tool first, so any context you add to oldString is verbatim rather than reconstructed.
  2. 02Expand oldString with more surrounding lines until it appears exactly once in the file.
  3. 03Or set replaceAll: true when you genuinely want every occurrence of oldString changed, not just one.
  4. 04For large mechanical rewrites spanning many locations, prefer apply_patch, which anchors on context and line sequences.
  5. 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 SeaShell in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install SeaShell

Related guides

Atlas vs. Ellipsis: Terminal AI Coding Agents in 2026

Atlas offers a terminal-native AI coding agent with permission-gated tools and local embeddings. Ellipsis provides a cloud platform for agents with live tracing and hard budget caps for 2026.

Atlas with Upstage Solar in 2026

Explore Upstage Solar models for Atlas in 2026. Leverage symmetric pricing and large context windows like 131,072 tokens with Solar Pro 3 for efficient coding tasks.

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) in 2026

Explore Atlas with Qwen2.5-Coder 32B (Ollama), the largest fully offline coding model for 24GB GPUs. Get free, air-gapped AI coding with a 32K token context window for your terminal in 2026.

Atlas with DeepCoder 14B (Ollama) in 2026

DeepCoder 14B (Ollama) provides Atlas developers a free, self-hosted model in 2026. Its 128K token context and RL tuning for first-attempt correctness are ideal for Atlas's unified diff workflow.

Atlas with DeepSeek V3 (open weights) in 2026

Drive Atlas with DeepSeek V3 (open weights), a 671B MoE model offering cost-effective coding assistance. Leverage its 128K context window for focused tasks.

Atlas vs PearAI: A Developer's Guide to AI Coding Agents in 2026

Comparing Atlas, the terminal-native AI coding agent, with PearAI, a VS Code fork aggregating open agents, for developers in 2026. Evaluate features, pricing, and ecosystem.

Atlas vs. Tabnine: Terminal AI Coding Agents in 2026

Comparing Atlas and Tabnine in 2026: Atlas is a terminal-native AI coding agent with permission-gated changes. Tabnine offers privacy-first code completion and chat, with on-prem deployment. Compare AI coding tools.

Browse this resource hub