earendil-works/pi · error · Error

Found occurrences of the text in . The text must be unique…

Error message

Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.

What it means

Single-edit ambiguity error from applyEditsToNormalizedContent: fuzzyFindText found more than one occurrence of oldText in the file, so the replacement target is not unique. Applying it would arbitrarily pick a location; the caller is told to include more surrounding context lines to disambiguate before retrying.

Solutions

  1. Add more surrounding context to oldText so it matches exactly one location in the file.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/agent/src/harness/tools/edit-diff.ts:331 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/ca5589b912f029c9. Report an issue: GitHub.

Appendix: source

Thrown at packages/agent/src/harness/tools/edit-diff.ts:331

			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);
		}

		matchedEdits.push({
			editIndex: i,
			matchIndex: matchResult.index,
			matchLength: matchResult.matchLength,
			newText: edit.newText,
		});
	}

	matchedEdits.sort((a, b) => a.matchIndex - b.matchIndex);
	for (let i = 1; i < matchedEdits.length; i++) {
		const previous = matchedEdits[i - 1];
		const current = matchedEdits[i];
		if (previous.matchIndex + previous.matchLength > current.matchIndex) {
			throw new Error(
				`edits[${previous.editIndex}] and edits[${current.editIndex}] overlap in ${path}. Merge them into one edit or target disjoint regions.`,
			);

View on GitHub (pinned to 4af9d21d3b)