FoundationAgents/OpenManus · error · ToolError

Invalid `insert_line` parameter: {insert_line}. It should be

Error message

Invalid `insert_line` parameter: {insert_line}. It should be within the range of lines of the file: {[0, n_lines_file]}

What it means

Thrown by str_replace_editor's insert operation when the insert_line argument is outside [0, n_lines_file]. The valid range is inclusive on both ends: 0 inserts before the first line and n_lines_file (the line count of the split content) appends after the last line.

Source

Thrown at app/tool/str_replace_editor.py:356

        return CLIResult(output=success_msg)

    async def insert(
        self,
        path: PathLike,
        insert_line: int,
        new_str: str,
        operator: FileOperator = None,
    ) -> CLIResult:
        """Insert text at a specific line in a file."""
        # Read and prepare content
        file_text = (await operator.read_file(path)).expandtabs()
        new_str = new_str.expandtabs()
        file_text_lines = file_text.split("\n")
        n_lines_file = len(file_text_lines)

        # Validate insert_line
        if insert_line < 0 or insert_line > n_lines_file:
            raise ToolError(
                f"Invalid `insert_line` parameter: {insert_line}. It should be within "
                f"the range of lines of the file: {[0, n_lines_file]}"
            )

        # Perform insertion
        new_str_lines = new_str.split("\n")
        new_file_text_lines = (
            file_text_lines[:insert_line]
            + new_str_lines
            + file_text_lines[insert_line:]
        )

        # Create a snippet for preview
        snippet_lines = (
            file_text_lines[max(0, insert_line - SNIPPET_LINES) : insert_line]
            + new_str_lines
            + file_text_lines[insert_line : insert_line + SNIPPET_LINES]
        )

View on GitHub (pinned to 52a13f2a57)

Solutions

  1. Clamp insert_line into [0, number_of_lines] before calling, re-reading the file to get the current line count.
  2. Remember the index is 0-based and the upper bound is the line count itself (insert-at-end is allowed).
  3. If appending to the file, pass exactly n_lines_file; if prepending, pass 0.
  4. Refresh your cached view of the file before computing the insertion point.

Example fix

// before
await editor.insert(path, insert_line=15, new_str='# note')  // file has 10 lines -> error
// after
lines = (await operator.read_file(path)).split('\n')
insert_line = min(15, len(lines))  # clamp to valid inclusive range [0, len(lines)]
await editor.insert(path, insert_line=insert_line, new_str='# note')
Defensive patterns

Strategy: validation

Validate before calling

n_lines = len((await operator.read_file(path)).expandtabs().split('\n'))
insert_line = max(0, min(insert_line, n_lines))  # clamp into inclusive [0, n_lines]

Type guard

def is_valid_insert_line(insert_line: int, n_lines: int) -> bool:
    return isinstance(insert_line, int) and 0 <= insert_line <= n_lines

Prevention

When it happens

Trigger: Calling insert with a negative insert_line, or an insert_line greater than the number of lines in the file. Common off-by-one confusion: the upper bound equals the total line count, not count-1, because inserting after the last line is legal.

Common situations: Agent code computing the insertion point from a stale view of the file (file shrank or was rewritten since read); passing a 1-based line number where the API expects a 0-based index plus treating the bound as exclusive; empty or one-line files where valid range is [0, 0] or [0, 1] and callers assume larger indices.

Related errors


AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15). Data as JSON: /api/errors/2df4c4ff71f860ea. Report an issue: GitHub.