Summary
find_filename can miss a valid filename when the surrounding fenced block markers have leading whitespace.
Aider already supports recovering filenames from fenced blocks, and the find_filename docstring includes an indented fence example. In the current implementation, the loop stops early because it checks the raw line with line.startswith("```") instead of checking the stripped line.
Steps to reproduce
Check out Aider main at commit 5dc9490bb35f9729ef2c95d00a19ccd30c26339c.
Add the following test inside TestUtils in tests/basic/test_editblock.py:
def test_find_filename_with_indented_fences(self):
fence = ("```", "```")
valid_fnames = ["dir/file3.py"]
lines = [" ```python", "file3.py", " ```"]
self.assertEqual(
eb.find_filename(lines, fence, valid_fnames),
"dir/file3.py",
)
Run:
python -m pytest tests/basic/test_editblock.py -q
Expected behavior
find_filename should treat indented fenced markers the same way as non-indented fenced markers when looking back for a filename, and return:
Actual behavior
The added regression test fails because find_filename returns None:
FAILED tests/basic/test_editblock.py::TestUtils::test_find_filename_with_indented_fences
AssertionError: None != 'dir/file3.py'
1 failed, 25 passed in 1.32s
Impact
When an LLM returns a SEARCH/REPLACE block with slightly indented fenced markers, Aider may fail to recover the filename even though the filename is present and matches a known repo file. This can make an otherwise valid edit block fail with a missing filename error.
Root cause
Inside find_filename, each candidate line is first normalized by strip_filename(line, fence), which strips whitespace before checking for fences.
But the continuation check uses the raw line:
if not line.startswith(fence[0]) and not line.startswith(triple_backticks):
break
For an indented fence like " ```", this condition becomes true and the loop breaks before it reaches the filename line.
Possible fix direction
Use a stripped line for the fence-continuation check:
stripped = line.strip()
if not stripped.startswith(fence[0]) and not stripped.startswith(triple_backticks):
break
A regression test should cover both plain fenced blocks and indented fenced blocks.
Version and model info
Aider: 0.86.3.dev, main@5dc9490bb35f9729ef2c95d00a19ccd30c26339c
Python: focused unit-level reproduction
Operating system: macOS
Installation: source checkout
Edit format: search/replace
Model: not applicable; reproduced by directly invoking deterministic filename parsing code
Summary
find_filenamecan miss a valid filename when the surrounding fenced block markers have leading whitespace.Aider already supports recovering filenames from fenced blocks, and the
find_filenamedocstring includes an indented fence example. In the current implementation, the loop stops early because it checks the raw line withline.startswith("```")instead of checking the stripped line.Steps to reproduce
Check out Aider main at commit
5dc9490bb35f9729ef2c95d00a19ccd30c26339c.Add the following test inside
TestUtilsintests/basic/test_editblock.py:Run:
Expected behavior
find_filenameshould treat indented fenced markers the same way as non-indented fenced markers when looking back for a filename, and return:Actual behavior
The added regression test fails because
find_filenamereturnsNone:Impact
When an LLM returns a SEARCH/REPLACE block with slightly indented fenced markers, Aider may fail to recover the filename even though the filename is present and matches a known repo file. This can make an otherwise valid edit block fail with a missing filename error.
Root cause
Inside
find_filename, each candidate line is first normalized bystrip_filename(line, fence), which strips whitespace before checking for fences.But the continuation check uses the raw line:
For an indented fence like
" ```", this condition becomes true and the loop breaks before it reaches the filename line.Possible fix direction
Use a stripped line for the fence-continuation check:
A regression test should cover both plain fenced blocks and indented fenced blocks.
Version and model info
Aider:
0.86.3.dev,main@5dc9490bb35f9729ef2c95d00a19ccd30c26339cPython: focused unit-level reproduction
Operating system: macOS
Installation: source checkout
Edit format: search/replace
Model: not applicable; reproduced by directly invoking deterministic filename parsing code