FoundationAgents/MetaGPT · error · LineNumberError

Invalid end line number: {end}. Line numbers must be between

Error message

Invalid end line number: {end}. Line numbers must be between 1 and {len(lines)} (inclusive).

What it means

Raised by Editor._edit_impl when the resolved end line is outside 1..len(lines). end defaults to len(lines) when None, so the error implies an explicit bad value: 0, negative, or an end line past the last line of the file. Note len(lines) for a file with trailing newline still equals the visible line count, so end = total_lines is legal but end = total_lines + 1 is not.

Source

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

            end: int: The end line number for editing.
            content: str: The content to replace the lines with.

        Returns:
            content: str: The new content of the file.
            n_added_lines: int: The number of lines added to the file.
        """
        # Handle cases where start or end are None
        if start is None:
            start = 1  # Default to the beginning
        if end is None:
            end = len(lines)  # Default to the end
        # Check arguments
        if not (1 <= start <= len(lines)):
            raise LineNumberError(
                f"Invalid start line number: {start}. Line numbers must be between 1 and {len(lines)} (inclusive)."
            )
        if not (1 <= end <= len(lines)):
            raise LineNumberError(
                f"Invalid end line number: {end}. Line numbers must be between 1 and {len(lines)} (inclusive)."
            )
        if start > end:
            raise LineNumberError(f"Invalid line range: {start}-{end}. Start must be less than or equal to end.")

        # Split content into lines and ensure it ends with a newline
        if not content.endswith("\n"):
            content += "\n"
        content_lines = content.splitlines(True)

        # Calculate the number of lines to be added
        n_added_lines = len(content_lines)

        # Remove the specified range of lines and insert the new content
        new_lines = lines[: start - 1] + content_lines + lines[end:]

        # Handle the case where the original lines are empty
        if len(lines) == 0:

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Clamp end to len(lines): end = min(end, total_lines)
  2. Omit end (pass None) to edit through the end of file
  3. Recount lines right before the edit rather than reusing cached totals

Example fix

// before
editor.edit(path, start=1, end=total_lines + 1, content='...')  # ValueError

// after
editor.edit(path, start=1, end=None, content='...')  # end defaults to len(lines)
Defensive patterns

Strategy: validation

Validate before calling

n = len(editor.current_file.read_text().splitlines())
end = n if end is None else min(end, n)
start = 1 if start is None else max(1, start)
editor.edit(path, start=start, end=end, content=content)

Type guard

def valid_end(end: int, n: int) -> bool:
    return 1 <= end <= n

Try / catch

try:
    editor.edit(path, start=s, end=e, content=c)
except LineNumberError:
    n = len(Path(path).read_text().splitlines())
    editor.edit(path, start=min(s, n), end=min(e, n), content=c)

Prevention

When it happens

Trigger: editor.edit(path, start=1, end=total+1) to 'include everything' (classic off-by-one); end=0; end derived from a diff hunk header of a newer file version.

Common situations: Off-by-one when replacing through the last line; stale end offsets after the file shrank; agents computing end as start + added_lines and overshooting.

Related errors


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