@deanrie
Thank you very much for the detailed response. I really appreciate it, and thank you for the additional contribution as well.
Yes, I understand the issue that the LLM thinks it is still inside an old string, and that is why it does not work. Of course, it is not efficient enough to reread the files in full every time beforehand just to get the current lines.
That said, if cost were irrelevant and the issue of inflating the context window were also irrelevant, then the easiest approach would naturally be to simply reread the files every time. From my own experience, I can definitely say that this always works. It is the simplest and easiest solution: through re-anchoring, you make sure that you continuously have the latest lines.
There is, for example, the first scenario where I, as the user, run ESLint AutoFix on a file or manually edit a file myself. Then, in an iterative process, when the LLM comes back to that file, if it does not do re-anchoring first, it fails.
The biggest issue I see behind this is that Cursor, with the Edit-File tool, tries to edit a large file, say 1,500 lines or so, using models like Opus 4.6 Max, for example. Then, only at the very end, on the last line, an error appears saying that the edit failed.
If you are working with a high-reasoning model, the model will first try to find the cause, and then additional token reasoning gets injected into the context. In practice, several euros are simply being thrown away here because the architecture is not modeled correctly in this respect.
If you compare it directly, it would actually be more cost-efficient to simply reread the files each time beforehand.
I can definitely say that I solved this whole issue through system prompts with re-anchoring. However, it is frustrating to keep building this into the system prompt, because I already have several additional things in the system prompt, such as in the other post I opened, where I mentioned that I cannot read the files with my MCP tools and they get saved into a local file instead, or that there are limits around the maximum number of files that can be read.
My system prompts are gradually starting to bloat, simply because my IDE does not provide these functionalities out of the box. And I already have very large system prompts anyway.
The additional problem I have is that the system prompt also keeps getting indexed into the context again and again. I understand that, from a prompting technique perspective, this is an efficient move, because continuously injecting the system prompt helps avoid hallucinations. But every one of these issues, let’s call them technical debts, where Cursor creates problem areas through certain tools or where I cannot work the way I want, has to be injected into the system prompt again and again, and that keeps being added to the context, which makes everything bloat further.
So the most efficient solution is definitely that Cursor MUST ensure that this does not happen.
At the end of the day, I’m not someone who builds AI, coding tools, extensions, or IDEs. So I don’t really know what the actual best practice is here, or how this should best be solved internally.
I don’t know whether continuous re-anchoring is the best approach, or whether it would make more sense to first check locally with some tools what the current lines are and then pass that to the LLM. But in my opinion, the end user should not have to pay for technical debt.
That means, first and foremost, the edit tool must be designed for cases like this. It should not run to 99% completion and only then show an error. It should somehow evaluate in advance whether this problem could occur, which should probably be possible.
Second, it should be considered whether re-anchoring could potentially be moved to the Cursor side in an isolated asynchronous process, with Cursor covering the cost.
I mean, this problem has effectively existed for several years already, and it’s nothing new that LLMs hallucinate and keep trying to perform re-replaces using old strings. You can see this across all IDEs and all extensions that try to edit files. In other words, edit tools always try to find the exact match for what needs to be edited. And if the exact match for the line and string cannot be found, then you get an error, etc. These are recurring problems.
That’s why I’m personally not really in favor of end users paying for failed edits. First for reading the file, then for the failed edit, and then afterward, with high-reasoning models, for the model to think through what just failed and retry the edit. Over the course of monthly usage, that adds up to hundreds of euros in technical debt paid by the end user.
If, instead, Cursor were to establish re-anchoring in an isolated, asynchronous way with its own model, for example before each individual file, and then provide the LLM with the new replace strings before the Edit File tool runs, it would probably be possible to reduce the error rate by more than 95%.
That’s just what’s coming to mind for me spontaneously right now. I really don’t know what the right solution is. But I strongly assume that if a bit of energy is put into this, these problems could be eliminated completely.