earendil-works/pi · error · Error
edits[ ].oldText must not be empty in .
Error message
edits[${editIndex}].oldText must not be empty in ${path}. What it means
Edit-application guard (multi-edit error variant): the edit at edits[editIndex] has an oldText that is empty after normalization. Because the edit API accepts an array, the message names the offending index (and edit count) so the caller can fix that specific edit; empty oldText is rejected before any matching is attempted.
Solutions
- Provide a non-empty oldText for every entry in the edits array.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/agent/src/harness/tools/edit-diff.ts:313 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of earendil-works/pi@4af9d21d3b (2026-08-24).
Data as JSON: /api/errors/b514d9212b7e13a5.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/harness/tools/edit-diff.ts:313
* All edits are matched against the same original content. Replacements are
* then applied in reverse order so offsets remain stable. If any edit needs
* fuzzy matching, the operation runs in fuzzy-normalized content space and then
* overlays those line-level changes onto the original content so unchanged line
* blocks keep their original bytes.
*/
export function applyEditsToNormalizedContent(
normalizedContent: string,
edits: Edit[],
path: string,
): AppliedEditsResult {
const normalizedEdits = edits.map((edit) => ({
oldText: normalizeToLF(edit.oldText),
newText: normalizeToLF(edit.newText),
}));
for (let i = 0; i < normalizedEdits.length; i++) {
if (normalizedEdits[i].oldText.length === 0) {
throw getEmptyOldTextError(path, i, normalizedEdits.length);
}
}
const initialMatches = normalizedEdits.map((edit) => fuzzyFindText(normalizedContent, edit.oldText));
const usedFuzzyMatch = initialMatches.some((match) => match.usedFuzzyMatch);
const replacementBaseContent = usedFuzzyMatch ? normalizeForFuzzyMatch(normalizedContent) : normalizedContent;
const matchedEdits: MatchedEdit[] = [];
for (let i = 0; i < normalizedEdits.length; i++) {
const edit = normalizedEdits[i];
const matchResult = fuzzyFindText(replacementBaseContent, edit.oldText);
if (!matchResult.found) {
throw getNotFoundError(path, i, normalizedEdits.length);
}
const occurrences = countOccurrences(replacementBaseContent, edit.oldText);
if (occurrences > 1) {
throw getDuplicateError(path, i, normalizedEdits.length, occurrences);View on GitHub (pinned to 4af9d21d3b)