{"record":{"id":"b514d9212b7e13a5","repo":"earendil-works/pi","slug":"edits-editindex-oldtext-must-not-be-empty-in","errorCode":null,"errorMessage":"edits[${editIndex}].oldText must not be empty in ${path}.","messagePattern":"edits\\[(.+?)\\]\\.oldText must not be empty in (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/harness/tools/edit-diff.ts","lineNumber":313,"sourceCode":" * All edits are matched against the same original content. Replacements are\n * then applied in reverse order so offsets remain stable. If any edit needs\n * fuzzy matching, the operation runs in fuzzy-normalized content space and then\n * overlays those line-level changes onto the original content so unchanged line\n * blocks keep their original bytes.\n */\nexport function applyEditsToNormalizedContent(\n\tnormalizedContent: string,\n\tedits: Edit[],\n\tpath: string,\n): AppliedEditsResult {\n\tconst normalizedEdits = edits.map((edit) => ({\n\t\toldText: normalizeToLF(edit.oldText),\n\t\tnewText: normalizeToLF(edit.newText),\n\t}));\n\n\tfor (let i = 0; i < normalizedEdits.length; i++) {\n\t\tif (normalizedEdits[i].oldText.length === 0) {\n\t\t\tthrow getEmptyOldTextError(path, i, normalizedEdits.length);\n\t\t}\n\t}\n\n\tconst initialMatches = normalizedEdits.map((edit) => fuzzyFindText(normalizedContent, edit.oldText));\n\tconst usedFuzzyMatch = initialMatches.some((match) => match.usedFuzzyMatch);\n\tconst replacementBaseContent = usedFuzzyMatch ? normalizeForFuzzyMatch(normalizedContent) : normalizedContent;\n\n\tconst matchedEdits: MatchedEdit[] = [];\n\tfor (let i = 0; i < normalizedEdits.length; i++) {\n\t\tconst edit = normalizedEdits[i];\n\t\tconst matchResult = fuzzyFindText(replacementBaseContent, edit.oldText);\n\t\tif (!matchResult.found) {\n\t\t\tthrow getNotFoundError(path, i, normalizedEdits.length);\n\t\t}\n\n\t\tconst occurrences = countOccurrences(replacementBaseContent, edit.oldText);\n\t\tif (occurrences > 1) {\n\t\t\tthrow getDuplicateError(path, i, normalizedEdits.length, occurrences);","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/earendil-works/pi/blob/4af9d21d3b4d664e4a29fcabfec85171077248e3/packages/agent/src/harness/tools/edit-diff.ts#L295-L331","documentation":"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.","triggerScenarios":"Thrown at packages/agent/src/harness/tools/edit-diff.ts:313 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Provide a non-empty oldText for every entry in the edits array."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4af9d21d3b4d664e4a29fcabfec85171077248e3","analyzedAt":"2026-08-24T13:07:14.692Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}