Make an old_string unique for a str_replace edit

Paste a file and the snippet you want to change. Get every match with line and column, and the shortest anchor that matches exactly once.

How it works

  1. Paste the file in the first box and the old string in the second
  2. Pick the match to edit when the snippet occurs more than once
  3. Copy the unique anchor and use it as the old string of the edit

How the unique anchor is found

To make an old string unique for a str_replace edit, add whole lines from above and below it until the longer text matches the file exactly once. This tool does that for you. It lists every place the snippet occurs with its line and column, takes the match you chose, and adds one line step above or below at a time. A step is a whole line; when the snippet starts or ends in the middle of a line, the first step takes in the rest of that line. It keeps the shortest result that no other match shares, then counts that anchor in the whole file again to prove it occurs once. Take a file with three functions that each contain the line " return null;" inside if (!user) {, if (!order) { and if (!item) {. The snippet occurs 3 times, at 4:1, 12:1 and 20:1. The lines below the first match are the same in all three places, so they cannot help, and the tool adds the one line above it: " if (!user) {" followed by the snippet occurs once. The page opens with this example.

Why an edit tool says not unique or not found

A tool that replaces an exact string needs to find it exactly once. Anthropic's text editor tool documents this for its str_replace command: old_str must match exactly, including whitespace and indentation, and an implementation should return an error both when nothing matches and when several places match. Patch formats that quote context lines fail in the same way when a quoted line differs from the file. When the count is zero, a common cause is a difference you cannot see: CRLF line endings in the file against LF in the snippet, tabs against spaces, spaces at the end of a line, curly quotes or an en dash that a chat window inserted, or a non-breaking space. With no exact match, this tool searches again with every run of whitespace treated as one space and curly quotes and dashes treated as plain ones. It lists those places, names what differs, such as tabs (the file uses tabs, the snippet spaces), prints the snippet exactly as it is written in the file, and builds the anchor from that text.

Options, limits and what it does not do

Which match to anchor picks one of several matches. The number is the # column of the table, and 1 is the first match in the file. Add context as lets you grow the anchor by line steps (whole lines), which is the default, or by single characters, which helps when two matches sit on one line. The search stops at 25 lines or 2,000 characters on each side, and at 400 characters in character mode, where an emoji counts as one character. If two matches are identical that far out, the tool says so instead of guessing. Matches are counted at every start position, so "aa" occurs twice in "aaa". The example code in Anthropic's text editor guide counts with Python's str.count, which counts non-overlapping matches and would say once, so the tool flags overlap, and the Replacement-safe tile reads No when the anchor also covers another match of the snippet. Up to 100,000 matches are compared, each box takes 1,000,000 characters, and the table lists the first 50. Browsers turn CRLF into LF when text is pasted, so switch on My file uses CRLF line endings if the file on disk does. The tool never edits a file and knows only the text you pasted. If the agent's copy of the file is different, its count can be different too.

Using it from an agent

An agent can open this page with both boxes filled in: add #input= followed by the URL-encoded file, and &input2= followed by the URL-encoded snippet, to the page address. Each box takes up to 100,000 characters this way. The text stays in the address fragment, which browsers do not send to a server. Encoded line breaks such as %0D%0A are kept until you edit the box, so a CRLF file stays CRLF. The anchor in the first result box is plain text. The Copy button copies it exactly, with the same line endings as the file. In the new string of the edit, keep the lines the anchor added and change only the snippet part.

Frequently asked questions

How do I fix "old_string is not unique" in a str_replace edit?

Add lines around the snippet until the longer text occurs once, and use that as the old string. In the sample, the line " return null;" occurs 3 times, and adding the line above it, " if (!user) {", makes it unique. Paste your file and snippet here and the shortest anchor is shown.

Why does str_replace say the string was not found when I can see it?

The text differs in a way that is hard to see: CRLF against LF, a tab against 4 spaces, spaces at the end of a line, curly quotes, an en dash or a non-breaking space. The tool matches ignoring those, names the difference, and shows the snippet as it is written in the file so you can copy it.

How many lines of context should I add?

As few as make the text unique. The tool adds one line step at a time, up to 25 lines or 2,000 characters on each side, and keeps the shortest anchor. A short anchor is less likely to break when the file changes. In character mode it adds single characters, up to 400 on each side.

What if I want to edit the second match, not the first?

Set Which match to anchor to 2. The table numbers every match with its line and column, such as 12:1, and marks the anchored one. The anchor for the second match can differ from the one for the first, because it is chosen against the other matches.

My file uses CRLF but the tool shows LF. Why?

Browsers change CRLF to LF when text is pasted into a box. Switch on My file uses CRLF line endings and the check runs on CRLF text, so an LF snippet is reported as a line-ending mismatch. A page opened with #input= keeps encoded %0D%0A until you edit the box.

Is my code uploaded?

No. The file and the snippet are processed in your browser, in this tab, and no server receives them. Your option choices are saved in this browser, the text is not.