earendil-works/pi · error · Error

oldText must not be empty in

Error message

oldText must not be empty in ${path}.

What it means

Edit-application guard in the coding-agent copy of applyEditsToNormalizedContent (single-edit variant): oldText is empty after line-ending normalization, so there is no text to locate and replace. Empty oldText is rejected before matching begins rather than matching at offset 0 and corrupting the file.

Solutions

  1. Provide a non-empty oldText for the edit.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/coding-agent/src/core/tools/edit-diff.ts:312 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/dcbf029a36cee4a2. Report an issue: GitHub.

Appendix: source

Thrown at packages/coding-agent/src/core/tools/edit-diff.ts:312

 * 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)