alibaba/open-code-review · error

invalid line range: start_line %d is greater than end_line %

Error message

invalid line range: start_line %d is greater than end_line %d

What it means

Validation error from FileReadProvider.Execute: when both start_line and end_line are provided (> 0), the requested range (end - start + 1) must be positive. If start_line > end_line the range is meaningless, so the tool refuses to read and returns this error instead of silently swapping or clamping the values.

Source

Thrown at internal/tool/file_read.go:42

	filePath, _ := args["file_path"].(string)
	if filePath == "" {
		return "Error: file_path is required", nil
	}

	startLine, hasStart := args["start_line"].(float64)
	endLine, hasEnd := args["end_line"].(float64)
	if !hasStart || startLine <= 0 {
		startLine = 1
	}
	if !hasEnd || endLine <= 0 {
		endLine = 0
	}

	maxLines := fileReadMaxLines
	if endLine > 0 {
		requested := int(endLine) - int(startLine) + 1
		if requested <= 0 {
			return "", fmt.Errorf("invalid line range: start_line %d is greater than end_line %d", int(startLine), int(endLine))
		}
		if requested < maxLines {
			maxLines = requested
		}
	}

	lines, totalLines, err := p.FileReader.ReadLines(ctx, filePath, int(startLine), maxLines)
	if err != nil {
		return "", fmt.Errorf("file %q not found: %w", filePath, err)
	}

	if totalLines > 0 && int(startLine)-1 >= totalLines {
		return "", fmt.Errorf("file %q has only %d lines, requested range %d-%d", filePath, totalLines, int(startLine), int(endLine))
	}

	effectiveEnd := totalLines
	if endLine > 0 && int(endLine) < effectiveEnd {
		effectiveEnd = int(endLine)

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Swap the values so start_line <= end_line, or read the whole file by omitting end_line.
  2. Re-fetch the file's current total line count and recompute the range.
  3. If you only need lines from start onward, pass start_line alone; end_line is optional.

Example fix

// before
{"file_path": "a.go", "start_line": 50, "end_line": 10}
// after
{"file_path": "a.go", "start_line": 10, "end_line": 50}
Defensive patterns

Strategy: validation

Validate before calling

start, end := int(args["start_line"].(float64)), int(args["end_line"].(float64))
if end > 0 && start > end {
    return fmt.Errorf("swap range: start_line %d > end_line %d", start, end)
}

Type guard

func validLineRange(start, end float64) bool { return start > 0 && (end <= 0 || start <= end) }

Try / catch

out, err := provider.Execute(ctx, args)
if err != nil && strings.Contains(err.Error(), "invalid line range") {
    args["start_line"], args["end_line"] = args["end_line"], args["start_line"]
    out, err = provider.Execute(ctx, args)
}

Prevention

When it happens

Trigger: Calling the file_read tool with args like {"start_line": 50, "end_line": 10} — any start_line strictly greater than end_line, where both are present and positive.

Common situations: An LLM agent computing line numbers from stale file metadata (file shrank between listing and reading); off-by-one when converting 0-based to 1-based indices; reversed slice arguments passed through from upstream tooling.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/17f5ec2eea9bce9a. Report an issue: GitHub.