Issue
Summary
In aider/coders/udiff_coder.py, UnifiedDiffCoder.apply_edits omits its partial-application notice when one hunk succeeds and another hunk fails.
The successful edit is written before ValueError is raised, but the error does not include the existing other_hunks_applied message indicating that some hunks were applied.
Steps to reproduce
-
Check out Aider main at commit 5dc9490bb35f9729ef2c95d00a19ccd30c26339c.
-
Add the following test inside TestUnifiedDiffCoder in tests/basic/test_udiff.py:
def test_apply_edits_reports_partial_success(self):
from pathlib import Path
from aider.coders import Coder
from aider.coders.udiff_coder import other_hunks_applied
from aider.io import InputOutput
from aider.models import Model
from aider.utils import GitTemporaryDirectory
with GitTemporaryDirectory():
success = Path("success.txt")
failure = Path("failure.txt")
success.write_text("old\n")
failure.write_text("different\n")
coder = Coder.create(
Model("gpt-3.5-turbo"),
"udiff",
io=InputOutput(yes=True),
fnames=[str(success), str(failure)],
stream=False,
)
edits = [
(str(success), ["-old\n", "+new\n"]),
(str(failure), ["-missing\n", "+replacement\n"]),
]
with self.assertRaises(ValueError) as error:
coder.apply_edits(edits)
self.assertEqual(success.read_text(), "new\n")
self.assertIn(
other_hunks_applied,
str(error.exception),
)
- Run:
python -m pytest tests/basic/test_udiff.py -q
- Observe that the newly added assertion fails while the four existing tests pass.
Expected behavior
For the focused batch, one of the two unique hunks is written successfully and the other produces an error. The raised ValueError is expected to include the module's existing other_hunks_applied marker:
Note: some hunks did apply successfully. See the updated source code shown above.
This marker is defined in aider/coders/udiff_coder.py. The same method contains an errors += other_hunks_applied statement guarded by len(errors) < len(uniq).
Actual behavior
success.txt is changed from old to new, confirming that one hunk was applied.
UnifiedDiffCoder.apply_edits then raises ValueError for failure.txt, but the exception does not include other_hunks_applied. The raised message describes only the failed hunk even though the successful edit has already been written.
The focused assertion that fails is:
self.assertIn(
other_hunks_applied,
str(error.exception),
)
The focused run summary is:
F.... [100%]
FAILED tests/basic/test_udiff.py::TestUnifiedDiffCoder::test_apply_edits_reports_partial_success
1 failed, 4 passed in 2.23s
Impact
A mixed-success edit leaves the workspace partially modified while reporting only the failed hunk.
The raised error does not include the function's existing partial-application notice, so the partial-success state is not disclosed in the error message.
Root cause
UnifiedDiffCoder.apply_edits initially stores one entry in errors for each failed hunk. It then joins the entries into a string before comparing its length with the number of submitted hunks:
if errors:
errors = "\n\n".join(errors)
if len(errors) < len(uniq):
errors += other_hunks_applied
raise ValueError(errors)
After the join, errors is a string, so len(errors) is the number of characters in the error message rather than the number of failed hunks.
For one failed hunk out of two unique hunks, the error string contains more than two characters. The condition is therefore false and other_hunks_applied is not appended.
Possible fix direction
Preserve the failed-hunk count before joining the error messages:
failed_count = len(errors)
message = "\n\n".join(errors)
if failed_count < len(uniq):
message += other_hunks_applied
raise ValueError(message)
Regression coverage should include all-success, all-failure, and mixed-success batches while verifying both the resulting file contents and error message.
Version and model info
Aider: 0.86.3.dev, main@5dc9490bb35f9729ef2c95d00a19ccd30c26339c
Python: 3.12.13
Operating system: macOS 15.7.3
Installation: source checkout; focused pytest reproduction
Edit format: udiff
Model: gpt-3.5-turbo model metadata used only to construct the coder; no provider request is made
Configuration: InputOutput(yes=True), stream=False
Issue
Summary
In
aider/coders/udiff_coder.py,UnifiedDiffCoder.apply_editsomits its partial-application notice when one hunk succeeds and another hunk fails.The successful edit is written before
ValueErroris raised, but the error does not include the existingother_hunks_appliedmessage indicating that some hunks were applied.Steps to reproduce
Check out Aider
mainat commit5dc9490bb35f9729ef2c95d00a19ccd30c26339c.Add the following test inside
TestUnifiedDiffCoderintests/basic/test_udiff.py:Expected behavior
For the focused batch, one of the two unique hunks is written successfully and the other produces an error. The raised
ValueErroris expected to include the module's existingother_hunks_appliedmarker:This marker is defined in
aider/coders/udiff_coder.py. The same method contains anerrors += other_hunks_appliedstatement guarded bylen(errors) < len(uniq).Actual behavior
success.txtis changed fromoldtonew, confirming that one hunk was applied.UnifiedDiffCoder.apply_editsthen raisesValueErrorforfailure.txt, but the exception does not includeother_hunks_applied. The raised message describes only the failed hunk even though the successful edit has already been written.The focused assertion that fails is:
The focused run summary is:
Impact
A mixed-success edit leaves the workspace partially modified while reporting only the failed hunk.
The raised error does not include the function's existing partial-application notice, so the partial-success state is not disclosed in the error message.
Root cause
UnifiedDiffCoder.apply_editsinitially stores one entry inerrorsfor each failed hunk. It then joins the entries into a string before comparing its length with the number of submitted hunks:After the
join,errorsis a string, solen(errors)is the number of characters in the error message rather than the number of failed hunks.For one failed hunk out of two unique hunks, the error string contains more than two characters. The condition is therefore false and
other_hunks_appliedis not appended.Possible fix direction
Preserve the failed-hunk count before joining the error messages:
Regression coverage should include all-success, all-failure, and mixed-success batches while verifying both the resulting file contents and error message.
Version and model info
Aider:
0.86.3.dev,main@5dc9490bb35f9729ef2c95d00a19ccd30c26339cPython:
3.12.13Operating system: macOS
15.7.3Installation: source checkout; focused pytest reproduction
Edit format:
udiffModel:
gpt-3.5-turbomodel metadata used only to construct the coder; no provider request is madeConfiguration:
InputOutput(yes=True),stream=False