danny-avila/LibreChat · warning · Error
old_text did not match the file content.
Error message
old_text did not match the file content.
What it means
Thrown by applyTextEdits when findReplacementMatch returns status 'none' for an edit's old_text — i.e. none of the four matching strategies (exact, line-trimmed, whitespace-normalized, indentation-flexible) could locate the text in the current file content. This is the file-authoring tool's 'old_text not found' failure, surfaced to the caller as a tool error via errorResult.
Source
Thrown at packages/api/src/agents/handlers.ts:1103
}
const whitespaceNormalized = findWhitespaceNormalizedMatch(content, needle);
if (whitespaceNormalized.status !== 'none') {
return whitespaceNormalized;
}
return findLineWindowMatch(content, needle, 'indentation-flexible');
}
function applyTextEdits(
content: string,
edits: TextEdit[],
): { content: string; strategies: string[] } {
let working = content;
const strategies: string[] = [];
for (const edit of edits) {
const match = findReplacementMatch(working, edit.old_text);
if (match.status === 'none') {
throw new Error('old_text did not match the file content.');
}
if (match.status === 'ambiguous') {
throw new Error(
`old_text matched ${match.count} locations with ${match.strategy}; make it unique before retrying.`,
);
}
working =
working.slice(0, match.index) + edit.new_text + working.slice(match.index + match.length);
strategies.push(match.strategy);
}
return { content: working, strategies };
}
function formatRange(start: number, count: number): string {
return count === 1 ? String(start) : `${start},${count}`;
}
View on GitHub (pinned to 5ff282f900)
Solutions
- Re-read the current file content and copy old_text verbatim from it (include surrounding unique context lines).
- Check for line-ending and tab/space mismatches; match the file's actual style.
- Confirm the correct filePath and that no other process mutated the file since the last read.
- Shorten old_text to a distinctive unique fragment if normalization is dropping it.
Example fix
// before
{ old_text: "function run() {\n return 1\r\n}", new_text: "function run() {\n return 2\n}" } // CRLF mismatch
// after
// re-read file, copy exact bytes including its real line endings
{ old_text: "function run() {\n return 1\n}", new_text: "function run() {\n return 2\n}" } Defensive patterns
Strategy: try-catch
Validate before calling
function findExactOccurrences(content: string, needle: string): number[] {
const out: number[] = [];
let from = 0;
while (true) {
const i = content.indexOf(needle, from);
if (i === -1) break;
out.push(i);
from = i + Math.max(1, needle.length);
}
return out;
}
// before calling applyTextEdits, verify old_text is present:
for (const e of edits) {
const hits = findExactOccurrences(currentContent, e.old_text);
if (hits.length === 0) throw new Error(`old_text not found: ${e.old_text.slice(0, 60)}...`);
} Type guard
function isOldTextPresent(content: string, oldText: string): boolean {
return content.includes(oldText);
} Try / catch
try {
const { content, strategies } = applyTextEdits(current.content, edits);
} catch (e) {
if (e instanceof Error && /old_text did not match/.test(e.message)) {
// re-read the file, recompute old_text from current bytes, and retry once
} else throw e;
} Prevention
- Always read the latest file content immediately before constructing edits; do not cache stale text.
- Normalize line endings and indentation in old_text to match the file's actual style.
- Include enough surrounding context in old_text that it is present and unique.
When it happens
Trigger: old_text that was never in the file; old_text copied from a different version of the file than the one currently on disk; whitespace/indentation differences larger than the normalization tolerates; old_text pointing at the wrong file path.
Common situations: The file was edited concurrently between read and write; the model hallucinated content; line-ending (CRLF vs LF) or tab/space differences exceed normalization; the file was reloaded with different formatting (a linter ran).
Related errors
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/79fd003d78b3e527.
Report an issue: GitHub.