FoundationAgents/MetaGPT · error · ValueError

Error: The `{position}_replaced_line_number` does not match

Error message

Error: The `{position}_replaced_line_number` does not match the `{position}_replaced_line_content`. Please correct the parameters.
The `{position}_replaced_line_number` is {line_number} and the corresponding content is "{true_content}".
But the `{position}_replaced_line_content ` is "{fake_content}".
The content around the specified line is:
{context}
Pay attention to the new content. Ensure that it aligns with the new parameters.

What it means

Raised by the line-based edit path (_edit_file_by_edit / _edit_file_with_line_numbers) when the caller-supplied replaced_line_content does not match what is actually at the supplied replaced_line_number. The editor verifies content-at-line as a safety check so stale or hallucinated line references cannot silently overwrite the wrong code; the message includes the true content, the claimed content, and surrounding context.

Source

Thrown at metagpt/tools/libs/editor.py:813

                    start = max(1, line_number - 3)
                    end = min(total_lines, line_number + 3)
                    context = "\n".join(
                        [
                            f'The {cur_line_number:03d} line is "{lines[cur_line_number-1].rstrip()}"'
                            for cur_line_number in range(start, end + 1)
                        ]
                    )
                    mismatch_error += LINE_NUMBER_AND_CONTENT_MISMATCH.format(
                        position=position,
                        line_number=line_number,
                        true_content=lines[line_number - 1].rstrip()
                        if line_number - 1 < len(lines)
                        else "OUT OF FILE RANGE!",
                        fake_content=line_content.replace("\n", "\\n"),
                        context=context.strip(),
                    )
        if mismatch_error:
            raise ValueError(mismatch_error)
        ret_str = self._edit_file_impl(
            file_name,
            start=first_replaced_line_number,
            end=last_replaced_line_number,
            content=new_content,
        )
        # TODO: automatically tries to fix linter error (maybe involve some static analysis tools on the location near the edit to figure out indentation)
        self.resource.report(file_name, "path")
        return ret_str

    def _edit_file_by_replace(self, file_name: str, to_replace: str, new_content: str) -> str:
        """Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.

        Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.

        Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.

        For example, given a file "/workspace/example.txt" with the following content:

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Re-read the file (editor.read/open_file) and re-extract the exact current line contents before editing
  2. Copy the content strings verbatim from the fresh read, preserving indentation
  3. If the file changed externally, restart from the new contents rather than patching stale references

Example fix

// before
editor._edit_file_by_line_numbers(path,
    first_replaced_line_number=42, first_replaced_line_content='def old():', ...)  # content mismatch

// after
# re-read window around line 42, then pass the exact current text
editor._edit_file_by_line_numbers(path,
    first_replaced_line_number=42, first_replaced_line_content='def newname():', ...)
Defensive patterns

Strategy: validation

Validate before calling

lines = Path(file_name).read_text().splitlines()
assert lines[line_number - 1].rstrip() == claimed_content.rstrip(), 'line/content drift'
# only then invoke the line-number edit

Type guard

def content_matches(path: str, line_number: int, claimed: str) -> bool:
    lines = Path(path).read_text().splitlines()
    return 0 < line_number <= len(lines) and lines[line_number - 1].rstrip() == claimed.rstrip()

Try / catch

try:
    result = editor._edit_file_by_edit(...)
except ValueError as e:
    if 'does not match' in str(e):
        fresh = editor.read(file_name)  # refresh, rebuild params, retry once
        raise

Prevention

When it happens

Trigger: Calling the line-number edit API where first/last_replaced_line_number point at lines whose actual text differs from the accompanying *_replaced_line_content values; using line numbers from an older version of the file; off-by-N line drift after earlier edits in the same session.

Common situations: LLM agents reusing line/content pairs from a previous read after the file changed; concurrent modifications by formatters or other agents; whitespace/indentation mismatches between the claimed and real content.

Related errors


AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14). Data as JSON: /api/errors/683a20e1ffc406ad. Report an issue: GitHub.